2012-02-02 134 views
0

我有一個程序需要將數據從C++傳遞到C#並返回進行處理。爲了做到這一點,我已經檢索了一個結構,將其轉換爲一個字節數組,然後在另一端將其轉換回來。但是,在將其轉換回來時,數據不正確,即使內存轉儲顯示每個變量的內存值都相同。傳遞結構似乎損壞數據

這裏是檢索值的代碼:

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; 

當看着他們:

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結構在內存轉儲中,pbKey,retVal,_PublicKey,cpiBuffer和cpi都具有完全相同的值。但是當將cpi看作一個結構時,Algorithm.pszObjId指向一些錯誤的內存位置,當我嘗試在函數中使用它時,它會失敗。我在這裏做錯了什麼?

+0

你是什麼意思「Algorithm.pszObjId指向一些錯誤的內存位置」?它是一個指針嗎? – 2012-02-02 16:44:13

+0

這是一個LPSTR。當我在表中擴展結構時,它指向的不是結構內部的存儲位置,而當我獲得原始值時,它指向結構內的位置。 – 2012-02-02 16:49:49

回答

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,這可能會造成一些困難。

+0

TCHAR *只是習慣的力量。這是扔在一起的代碼,而不是生產。 如果不是來自鑄造,我會如何獲得原始結構? – 2012-02-02 17:04:01

+0

我沒有確定的答案,因爲我不知道如何創建這些結構,誰分配字符串以及誰負責釋放它。但我猜你可以創建一個函數,該函數知道如何序列化結構,按成員的成員,將字符串序列化爲以空字符結尾的字符數組或帶有大小前綴。 – 2012-02-02 17:30:37

+0

對CryptExportPublicKeyInfo的第一個調用返回CERT_PUBLIC_KEY_INFO結構所需的緩衝區的長度。然後我分配這些內存並再次調用該函數,並將數據傳遞到緩衝區。 – 2012-02-02 18:09:13