2010-01-13 3 views
0

En wincrypt.h je vois:Conversion: #define xxxxxx ((LPCSTR) 4)

#define CERT_CHAIN_POLICY_SSL ((LPCSTR) 4) 

WINCRYPT32API BOOL WINAPI CertVerifyCertificateChainPolicy(
    IN LPCSTR pszPolicyOID, 
    IN PCCERT_CHAIN_CONTEXT pChainContext, 
    IN PCERT_CHAIN_POLICY_PARA pPolicyPara, 
    IN OUT PCERT_CHAIN_POLICY_STATUS pPolicyStatus 
    ); 

Le premier argument prend CERT_CHAIN_POLICY_SSL. Cela semble être un pointeur vers une chaîne C, mais c'est un entier !?

Le pointeur est évidemment un entier de 32 bits, mais à quoi pointe-t-il? Si le nombre est < 255, il prendra un seul octet, ainsi la chaîne C est-elle en fait une simple "chaîne" d'octets (c'est-à-dire un octet)?

Lors de la convocation dans une autre langue qui supporte les variables BYTE, je peux simplement créer un bVar (une variable BYTE) et l'assigner 4. Ensuite, je peux passer un pointeur vers cette variable BYTE?

Répondre

1

Parfois, une API prend un paramètre qui peut être un «cookie» ou un ID pour un objet connu ou un pointeur vers un nom (par exemple), ce qui semble être le cas ici. 4 est un cookie/handle/ID pour la politique bien connue CERT_CHAIN_POLICY_SSL. Certains utilisateurs de l'API peuvent spécifier une politique qui n'est pas connue à l'avance de la bibliothèque, mais elle est spécifiée par un nom qu'elle peut rechercher quelque part (ou comme le registre, le fichier de configuration ou autre).

Dans la même veine, GetProcAddress() peut prendre un pointeur sur le nom de la fonction pour laquelle vous voulez que l'adresse (qui est utilisée aujourd'hui dans 99% des cas), ou sur le paramètre pointeur vers une chaîne peut être un nombre qui spécifie l'ordinal de la fonction.

Les paramètres de pointeur de surcharge comme ceci sont des techniques malheureuses qui sont parfois utilisées pour rendre une API plus flexible. Heureusement, ce n'est pas particulièrement commun. De toute façon, si vous voulez appeler cette API à partir d'une autre langue et spécifier la politique CERT_CHAIN_POLICY_SSL, vous devez passer un 4 pour la valeur du pointeur (pas un pointeur pointant vers la valeur 4).

+0

Bon travail, maintenant ma réponse ne sera pas votée parce que la vôtre est plus longue! :) – wj32

1

Le pointeur ne pointe sur rien. Sur un système 32 bits, ce sera un pointeur (presque certainement invalide) avec la valeur 0x00000004.

Comme pour les autres langages, en C# par exemple, il est susceptible d'être appelé comme System.IntPtr.

On pourrait penser à ce casting méchant comme un moyen paresseux de faire

union StringOrInteger 
{ 
    const char* str; 
    int n; 
}; 
0

Non, vous ne pouvez pas passer un pointeur vers une BYTE tenant la valeur. Cela conduirait l'API C à "voir" une valeur de pointeur qui est une adresse vraie (l'adresse de ce BYTE), pas le petit entier passé comme un pointeur attendu.

Il n'y a pas de chaîne, c'est simplement l'utilisation de la valeur du pointeur. Qu'il soit déclaré comme un pointeur sur une chaîne n'a pas d'importance, il pourrait tout aussi bien être un pointeur vers un flotteur, ou (mieux) void*.

1

Vous devez comprendre que certaines API sont conçues pour être aussi courtes et compactes que possible, même si cela signifie que les utilisateurs peuvent être déroutants. Par exemple, la fonction CreateDialog vous permet de spécifier un identificateur de ressource de chaîne. Mais vous pouvez également spécifier des identificateurs d'entiers. Donc Microsoft a décidé que vous pouviez passer un identifiant entier dans le même argument (un pointeur!). Cela peut être la même chose ici - cette fonction peut vous permettre de spécifier un ID de stratégie de chaîne ou un nombre entier. Pour la compacité, les deux formes sont passées dans le même argument.

+0

Juste curieux, comment pointeriez-vous à une politique de chaîne quand le pointeur EST la valeur requise? –

+0

Vous passez le pointeur de chaîne. Il y aurait une limite à la plage d'identifiants d'entiers possibles - par exemple, des valeurs inférieures à 0x1000 pourraient leur être réservées, puisque ces pages sont réellement inutilisables et ne peuvent pas contenir de chaînes. – wj32