C++ Windows 函数 "LockResource()" returns 资源中的一半数据

C++ Windows function "LockResource()" returns half the data in the resource

我正在尝试从 dll 中读取嵌入式资源,它包含一个加密文件。从 LockResource() 读取它,只有 returns 一半的数据。

有趣的是我检查了 SizeOfResource() 资源的大小是应该的。

所以我尝试在没有嵌入资源的情况下访问该文件:

 std::ifstream enc("Logs.enc" , std::ios::binary);              // Accessing encrypted file
    std::string ciphertext = std::string((std::istreambuf_iterator<char>(enc)), std::istreambuf_iterator<char>());
    int size = ciphertext.size();   //  Returns the correct size

这行得通,我试图找到它们的共同点,并尝试删除 std::ios::binary,它的行为与将文件作为资源访问时的行为相似。

这是我尝试将其作为资源访问的尝试:

 HGLOBAL SHEET_DATA;      // Imagine this has the encrypted file
        if (SHEET_DATA) {
            char* datac = nullptr;
            datac = (char*)LockResource(SHEET_DATA);
             std::string data = datac;
            long size_sheet = SizeofResource(dll, SHEET);  // 

            int real_size = data.size();    // Returns the wrong size
        }

我试图搜索是否有诸如 LockResource() 函数之类的以二进制模式访问数据的函数,但我找不到任何结果。

谢谢

strlen 假设参数是零终止字符串。它计算字符直到到达零终止。

在你的情况下,资源似乎是二进制的。在这种情况下,它可能包含值为 0 的字节,strlen 将其视为字符串的结尾。

因此 strlen returns 是无关紧要的。您可以使用从 SizeofResource 返回的 size_sheet 来了解 datac.

指向的数据的大小

更新: 更新后的问题不再包含 strlen 的用法。但是行:

std::string data = datac;

创建一个类似的问题。从 char* 初始化 std::string 假定 char* 指向零终止字符串。因此,如果缓冲区包含零,则生成的字符串将仅包含直到第一个零的字符。 您可以通过以下方式初始化 std::string 以避免零终止假设:

std::string data(datac, size_sheet); 

将缓冲区的长度提供给 std::string 的构造函数将强制使用完整的缓冲区进行初始化(忽略零)。

Update2: 正如@IInspectable 在下面评论的那样,如果数据不是真正的字符串,最好将其保存在更合适的容器中 - 例如std::vector<char>。它还有一个接受 char* 和缓冲区长度的构造函数。

问题出在这一行:

 std::string data = datac;

这从 null-terminated 字符串构造了 std::string。但是 datac 不是 null-terminated 字符串,正如您所说的那样,它是二进制数据。相反,使用 string (const char* s, size_t n); ctor 重载:

 std::string data(datac, size_sheet);