Передача структуры может повредить данные - PullRequest
0 голосов
/ 02 февраля 2012

У меня есть программа, которая должна передавать данные из 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 голосов
/ 02 февраля 2012
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, и это может создать некоторые трудности.

...