Question

Lorsque vous maintenez une interface COM , un BSTR vide doit-il être traité de la même manière que NULL ? En d'autres termes, ces deux appels de fonction doivent-ils produire le même résultat?

 // Empty BSTR
 CComBSTR empty(L""); // Or SysAllocString(L"")
 someObj->Foo(empty);

 // NULL BSTR
 someObj->Foo(NULL);     
Était-ce utile?

La solution

Oui - un BSTR NULL est identique à un vide. Je me souviens que nous avons eu toutes sortes de bugs qui ont été découverts lorsque nous sommes passés de VS6 à 2003 - la classe CComBSTR a été modifiée pour le constructeur par défaut qui l’a alloué en utilisant NULL plutôt qu’une chaîne vide. Cela se produit lorsque, par exemple, vous traitez un BSTR comme une chaîne de style C normale et le transmettez à une fonction telle que strlen , ou essayez d'initialiser un std :: string avec ce dernier.

Eric Lippert présente BSTR en détail dans le guide complet d'Eric. Sémantique BSTR :

  

Permettez-moi d’énumérer les différences en premier et   puis discuter de chaque point dans   détail atroce.

     

1) Un BSTR doit avoir identique   sémantique pour NULL et pour "". Un PWSZ   a fréquemment une sémantique différente pour   ceux.

     

2) Un BSTR doit être alloué et libéré   avec la famille SysAlloc * de   les fonctions. Une PWSZ peut être un   mémoire tampon automatique de la   pile ou alloué avec malloc, nouveau,   LocalAlloc ou toute autre mémoire   allocateur.

     

3) Un BSTR est de longueur fixe. Un PWSZ   peut être de n'importe quelle longueur, limitée seulement par   la quantité de mémoire valide dans son   tampon.

     

4) Un BSTR pointe toujours vers le premier   caractère valide dans le tampon. Un PWSZ   peut être un pointeur vers le milieu ou la fin   d'un tampon de chaîne.

     

5) Lorsque vous allouez un BSTR de n octets, vous   avoir de la place pour n / 2 caractères larges.   Lorsque vous allouez n octets pour un PWSZ   vous pouvez stocker n / 2 - 1 caractères -   vous devez laisser de la place pour le null.

     

6) Un BSTR peut contenir n’importe quelle donnée Unicode   y compris le caractère zéro. Un PWSZ   ne contient jamais le caractère zéro   sauf comme marqueur de fin de chaîne.   Un BSTR et un PWSZ ont toujours un   zéro caractère après leur dernier valide   caractère, mais valide dans un BSTR   caractère peut être un caractère zéro.

     

7) Un BSTR peut en fait contenir un impair   nombre d'octets - il peut être utilisé pour   déplacer des données binaires. Une PWSZ est   presque toujours un nombre pair d'octets   et utilisé uniquement pour stocker Unicode   chaînes.

Autres conseils

Le moyen le plus simple de gérer ce dilemme consiste à utiliser CComBSTR et à vérifier que .Length () est égal à zéro. Cela fonctionne pour les valeurs vides et NULL.

Cependant, gardez à l'esprit que vous devez libérer BSTR vide ou une fuite de mémoire risque de se produire. J'ai vu certains de ceux récemment dans le code de l'autre. Difficile à trouver, si vous ne regardez pas attentivement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top