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);
我正在尝试从 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);