Откуда вы знаете, что некоторые поля в структурах являются массивами? - PullRequest
0 голосов
/ 11 мая 2018

Я смотрю на этот кусок кода C из файла заголовка Microsoft wincrypt.h

//+-------------------------------------------------------------------------
//  Attributes
//
//  Where the Value's PATTR_BLOBs are in their encoded representation.
//--------------------------------------------------------------------------
// certenrolls_begin -- CRYPT_ATTRIBUTE
typedef struct _CRYPT_ATTRIBUTE {
    LPSTR               pszObjId;
    DWORD               cValue;
    PCRYPT_ATTR_BLOB    rgValue;
} CRYPT_ATTRIBUTE, *PCRYPT_ATTRIBUTE;

typedef struct _CRYPT_ATTRIBUTES {
    DWORD                cAttr;
    PCRYPT_ATTRIBUTE     rgAttr;
} CRYPT_ATTRIBUTES, *PCRYPT_ATTRIBUTES;
// certenrolls_end

и я запускаю этот пример Как получить информацию из исполняемых файлов с подписью Authenticode . В коде видно, что к rgValue и rgAttr обращаются как к массивам, например,

pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].pbData,
pSignerInfo->AuthAttrs.rgAttr[n].rgValue[0].cbData,

Если бы я не видел пример, я бы никогда этого не понял. Это что-то специфичное для Windows или мое полное незнание о объявлениях структуры и типов в C?

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

PCRYPT_ATTR_BLOB равно CRYPT_ATTR_BLOB*, указатель на CRYPT_ATTR_BLOB. Это может быть либо указатель на одно значение, либо указатель на массив. Вы не можете узнать из объявления типа и должны прочитать документацию.

Это документация говорит:

cValue

A DWORD значение, которое указывает количество элементов в rgValue массив.

rgValue

Указатель на массив CRYPT_INTEGER_BLOB структур.

Так что в этом случае rgValue является указателем на массив.

0 голосов
/ 11 мая 2018

Обратите внимание, что MS довольно постоянна в оформлении имен в венгерском стиле, префикс "rg" сообщает вам, что это массив, даже не заходя в документы.

0 голосов
/ 11 мая 2018

rgAttr и rgValue имеют указатель типа на struct:

typedef struct _CRYPT_ATTRIBUTES *PCRYPT_ATTRIBUTES;
typedef struct _CRYPT_ATTRIBUTE *PCRYPT_ATTRIBUTE;

Теперь, когда вы выполните PCRYPT_ATTRIBUTE rgAttr, оно будет эквивалентно struct _CRYPT_ATTRIBUTE *rgAttr и CRYPT_ATTRIBUTE *rgAttr.

Вообще говоря, использование typedef на pointers имеет только недостатки.Единственный случай, когда typedef на pointer действительно полезен, это когда указатель является указателем на функцию.

...