9
votes

Comment mieux convertir cstring en BSTR pour la transmettre en tant que paramètre "in" dans une méthode COM?

J'ai besoin de convertir une instance code> cstring code> dans un BSTR correctement attribué et transmettez-le que bstr code> dans une méthode COM. Pour avoir du code qui compile et fonctionne avec intérêt pour ANSI et UNICODE I utilise cstring :: AllocsySstring () code> pour convertir le format cstring code> à un ericode BSTR.

Depuis personne Possède le retour BSTR Je dois m'en occuper et la libérer après que l'appel soit effectué de la manière la plus sûre possible posable et avec le moins de code possible. P>

Actuellement, j'utilise ATL: : CCOMBSTR CODE> pour la gestion de la vie: P>

 ATL::CComBSTR converted;
 converted.Attach( sourceString.AllocSysString() ); //simply attaches to BSTR, doesn't reallocate it
 interface->CallMethod( converted );


0 commentaires

3 Réponses :


16
votes

CCOMBSTR code> a des constructeurs surchargés pour les deux char * code> et wchar_t * code>, qui apportez l'appel à sysallocstring () code > en votre nom. Donc, l'allocation explicite dans votre extrait de code est réellement inutile. Ce qui suit fonctionnerait également:

interface->CallMethod(ATL::CComBSTR(sourceString));


6 commentaires

Cela fonctionnera certainement, sauf que, avec l'utilisation de CCOMBSTR Constructor, je devrai vérifier que la répartition BSTR a été réussie (CSSTRING :: AllocsSstring () Faire la vérification et jette une exception) et je vais devoir prendre soin de _Com_issue_error () fonction - soit le remplacer par latéralement ou attrapez _Com_Error.


Pourquoi ne pas laisser la méthode appelée être responsable de la vérification de la validité de ses propres arguments? Si l'allocation échoue, CCOMBSTR :: m_str sera null. Donc, soit la méthode appelée vérifiera NULL et retournera e_invalidarg , ou le même attrape que vous avez déjà pour cstring :: ALLOCSYSSSTRING () peut gérer l'exception pour vous. C'est un idiome plus propre que d'exécuter explicitement le chèque vous-même, IMHO.


@Phil Booth: La méthode appelée peut interpréter Null BSTR comme cas particulier. Par exemple, la signification pourrait être "Spécifie un nom de fichier, si la chaîne vide est passée, le nom de fichier par défaut est utilisé". La méthode étant appelée pourrait donc avoir aucune chance de savoir qu'il y a un problème.


C'est une règle fondamentale du comité qu'il n'y a pas de différence sémantique entre un null BSTR et une "longueur nulle". Si certains composants que vous appelez différenciés entre les deux, c'est un bug. Voir cette réponse pour plus d'informations: Stackoverflow.com/questions/171641/...


@Phil Booth: Yeap, je sais. Le problème est que je viens d'appeler invokemethod (CCOMBSTR (SourceString)) La méthode appelée n'aurait aucune idée de la raison pour laquelle est la null de la null btr, car il est là pour indiquer une chaîne vide ou parce que Sysallocstring () appelé à l'intérieur de la mémoire de CCOMBSTR Constructeur pénurie.


Oh, mon mal, je vous ai mal compris, désolé. Vous avez un bon point.



2
votes

L'un des aspects déroutants de la programmation Windows gère la conversion des chaînes de style de base visuelles vers / depuis les chaînes de style language. Ce n'est pas si difficile, il est simplement difficile de se souvenir des détails. Il n'est généralement pas fait souvent et la documentation MSDN est tellement volumineuse qu'il est difficile de trouver des réponses à vos questions. Mais, la pire partie est que vous pouviez effectuer un peu de caractères qui compilait bien, mais ne fonctionne pas comme vous vous attendez. Cela se traduit par code qui ne fonctionne pas et les bugs sont difficiles à suivre. Après une certaine expérience, vous apprenez à vous assurer que vos conversions de chaîne font ce que vous attendez.

C Strings sont des tableaux de caractères terminés par un caractère nul. Les chaînes de base visuelles diffèrent en ce que la longueur de la chaîne précède les caractères de la chaîne. Donc, une chaîne VB connaît sa propre longueur. De plus, toutes les chaînes VB sont unicode (16 bits par caractère). Types de chaîne p>

Les conversions de chaîne BSTR / C sont requises si: P>

You are doing COM programming in C/C++
You are writing multiple language applications, such as C++ DLL's accessed by Visual Basic applications.


0 commentaires

2
votes

L'un des _bstr_t code> constructeurs vous permet de joindre simplement au btr code> existant afin que vous puissiez avoir l'exception que vous souhaitez à partir de cstring :: AllocsySstring Code > Lorsque BSTR code> L'allocation échoue échoue.

_bstr_t(
   BSTR bstr,
   bool fCopy 
);


0 commentaires