传递结构似乎会损坏数据
我有一个程序需要将数据从 C++ 传递到 C# 并返回进行处理。为了做到这一点,我检索了一个结构,将其转换为字节数组,然后在另一端将其转换回来。然而,当将其转换回来时,数据不正确,即使内存转储显示每个变量在内存中的值是相同的。
下面是检索该值的代码:
array<Byte> ^ GetPublicKeyBlob(String ^ ContainerName) {
const TCHAR * tContainer = context->marshal_as<const TCHAR*>(ContainerName);
HCRYPTPROV hProv = NULL;
CryptAcquireContext(&hProv, tContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET);
DWORD dwKeySize = 0;
CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING, NULL, &dwKeySize);
PCERT_PUBLIC_KEY_INFO pbKey = (PCERT_PUBLIC_KEY_INFO)calloc(dwKeySize, sizeof(BYTE));
CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING, (PCERT_PUBLIC_KEY_INFO)pbKey, &dwKeySize);
array<Byte> ^ retVal = gcnew array<Byte>(dwKeySize);
for(int i = 0; i < dwKeySize; i++)
retVal[i] = ((BYTE*)pbKey)[i];
free(pbKey);
return retVal;
}
然后在另一端,我使用以下代码将其更改回 PCERT_PUBLIC_KEY_INFO 结构:
BYTE * cpiBuffer = (BYTE*)calloc(_PublicKey->Length, sizeof(BYTE));
for(int i = 0; i < _PublicKey->Length; i++)
cpiBuffer[i] = _PublicKey[i];
PCERT_PUBLIC_KEY_INFO cpi = (PCERT_PUBLIC_KEY_INFO)cpiBuffer;
在内存转储中查看它们时,pbKey、retVal、_PublicKey、cpiBuffer 和 cpi 都具有准确的值相同的价值观。但是,当将 cpi 视为结构时,Algorithm.pszObjId 指向一些错误的内存位置,当我尝试在函数中使用它时,它会失败。我在这里做错了什么?
I have a program that needs to pass data from C++ to C# and back for processing. In order to do this, I have retrieved a structure, converted it into a byte array and then converted it back on the other end. However, when converting it back, the data is not correct, even though the memory dump shows that the values in memory for each variable are identical.
Here is the code to retrieve the value:
array<Byte> ^ GetPublicKeyBlob(String ^ ContainerName) {
const TCHAR * tContainer = context->marshal_as<const TCHAR*>(ContainerName);
HCRYPTPROV hProv = NULL;
CryptAcquireContext(&hProv, tContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET);
DWORD dwKeySize = 0;
CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING, NULL, &dwKeySize);
PCERT_PUBLIC_KEY_INFO pbKey = (PCERT_PUBLIC_KEY_INFO)calloc(dwKeySize, sizeof(BYTE));
CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING, (PCERT_PUBLIC_KEY_INFO)pbKey, &dwKeySize);
array<Byte> ^ retVal = gcnew array<Byte>(dwKeySize);
for(int i = 0; i < dwKeySize; i++)
retVal[i] = ((BYTE*)pbKey)[i];
free(pbKey);
return retVal;
}
Then on the other end, I change it back to a PCERT_PUBLIC_KEY_INFO structure with the following code:
BYTE * cpiBuffer = (BYTE*)calloc(_PublicKey->Length, sizeof(BYTE));
for(int i = 0; i < _PublicKey->Length; i++)
cpiBuffer[i] = _PublicKey[i];
PCERT_PUBLIC_KEY_INFO cpi = (PCERT_PUBLIC_KEY_INFO)cpiBuffer;
When looking at them in a memory dump, pbKey, retVal, _PublicKey, cpiBuffer and cpi all have the exact same values. But when looking at cpi as a structure, the Algorithm.pszObjId points to some erroneous memory location and when I try to use it in a function, it fails. What am I doing wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

如您所见,pszObjId 是一个指针,它的内容位于内存中的某个位置。通过将 PCERT_PUBLIC_KEY_INFO 结构转换为字节数组,您只能获取指针的值,而不是它指向的内容。
顺便说一句,我不确定为什么要编组为 TCHAR*,如果您想要字节,那么您应该使用 char* 或 unsigned char*。如果定义了 UNICODE,则 TCHAR 将是 wchar_t,这可能会带来一些困难。
As you can see, pszObjId is a pointer, it's contents are somewhere in memory. By casting the PCERT_PUBLIC_KEY_INFO structure to byte array you are only getting the value of the pointer, not what it points to.
On a side note, I'm not sure why are you marshaling as TCHAR*, if you want bytes then you should use char* or unsigned char*. If UNICODE is defined TCHAR will be wchar_t and that might make some difficulties.