传递结构似乎会破坏数据

时间:2012-02-02 16:28:40

标签: c# c++ interop c++-cli cryptoapi

我有一个程序需要将数据从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指向一些错误的内存位置,当我尝试在函数中使用它时,它会失败。我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

typedef struct _CRYPT_ALGORITHM_IDENTIFIER {
  LPSTR            pszObjId;
  CRYPT_OBJID_BLOB Parameters;
} CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER;

正如您所看到的,pszObjId是一个指针,它的内容位于内存中的某个位置。通过将PCERT_PUBLIC_KEY_INFO结构转换为字节数组,您只获得指针的值,而不是它指向的值。

另一方面,我不确定你为什么要编组为TCHAR *,如果你想要字节,那么你应该使用char *或unsigned char *。如果定义了UNICODE,则TCHAR将是wchar_t,这可能会带来一些困难。