2009-02-23 6 views
3

Jusqu'ici, j'ai découvert que je peux convertir les BSTR entrants en ANSI de deux façons (parmi de nombreuses?), Et je suis curieux de savoir si l'un est meilleur que l'autre en termes de vitesse/efficacité ...Quel est le meilleur code pour convertir les paramètres BSTR en ANSI en C/C++?

La façon dont j'ai été utilisé pendant un certain temps est d'utiliser les macros USES_CONVERSION et W2A, par exemple

BSTR __stdcall F(BSTR p1, BSTR p2) { 
    USES_CONVERSION; 

    LPSTR sNum1 = W2A(p1); 
    LPSTR sNum2 = W2A(p2); 

Récemment, cependant, je suis tombé sur une autre technique:

BSTR __stdcall F(BSTR p1, BSTR p2) { 
    long amt = wcstombs(NULL, p1, 1); 
    sNum1 = (char *) malloc(amt); 
    wcstombs(sNum1, p1, amt); 
    *(sNum1 + amt) = '\0'; 

    amt = wcstombs(NULL, p2, 1); 
    sNum2 = (char *) malloc(amt); 
    wcstombs(sNum2, p2, amt); 
    *(sNum2 + amt) = '\0'; 

Maintenant, je vous accorde, il est verbeux, et a deux appels à wcstombs mais pour tout ce que je connais les macros USES_CONVERSION et W2A peuvent être cacher toutes sortes d'amusement et de jeux.

Quel est le code le plus efficace/le plus rapide? Ou y a-t-il une autre technique que je pourrais utiliser qui ferait mieux le travail?

+0

Le second code a un comportement non défini, car il écrit au-delà la fin du tampon alloué. –

Répondre

3

Notez dans la réponse approuvée par Nick, qui partage correctement le même problème il existe avec la documentation MSDN qui décrit les macros.

Le problème est que certaines des macros telles que celles répertoriées par @Nick-COLE2A n'existent pas réellement.

Cependant, plus bas sur la page MSDN, il y a du texte qui vous indique ce fait et vous permet de déterminer la bonne macro!

Le texte figure dans le tableau sous le texte suivant:

Il existe plusieurs différences importantes entre les macros de conversion de chaînes plus anciennes et les nouvelles classes de conversion de chaîne:

Dans le New ATL 7.0 Colonne Classes de conversion.

qui dit:

OLE est toujours équivalent à W

Ainsi la macro dans @ exemple Nick est en fait CW2A

+0

Nasty ... merci pour ce peu d'infos. Très utile. – bugmagnet

6

De MSDN:

[...] La méthode recommandée de convertir en chaînes BSTR est d'utiliser la classe CComBSTR. Pour convertir en BSTR, passez la chaîne existante au constructeur de CComBSTR. Pour convertir à partir d'un BSTR, utilisez COLE2 [C] DestinationType [EX], tel que COLE2T.

Sur la page CComBSTR:

[...] La classe CComBSTR fournit un certain nombre de membres (constructeurs, opérateurs d'affectation, et les opérateurs de comparaison) qui prennent soit des chaînes ANSI ou Unicode comme arguments. Les versions ANSI de ces fonctions sont moins efficaces que leurs homologues Unicode car les chaînes Unicode temporaires sont souvent créées en interne. Pour plus d'efficacité, utilisez les versions Unicode lorsque cela est possible.

3

Note:

Si vous utilisez les macros ATL, par exemple: COLE2 [C] DestinationType [Ex] (que vous devriez probablement), assurez-vous d'utiliser les versions 'C' possible, pas les versions non-const comme vous l'avez écrit. Ils peuvent être équivalents pour des conversions BSTR-> ASCII explicites (par exemple: COLE2A), mais pour les conversions sans conversion réelle (par exemple: COLE2T lors de la compilation pour UNICODE), les versions 'C' peuvent être étendues à noops, tandis que les non Les versions -'C 'copieront toujours si la chaîne source est const (parce que vous exprimez que vous avez besoin que la chaîne résultante soit non-const).

A noter également:

Les nouvelles macros ATL7 ne nécessitent pas toujours USES_CONVERSION, mais ils allouent des objets temporaires valeur r, alors que les anciennes macros utilisent _alloca. Cela peut ou non être important, selon votre utilisation (par exemple, NE PAS utiliser les anciennes macros dans une boucle qui fonctionne un grand nombre de fois, vous pouvez souffler la pile en faisant cela).

1

Cela fait longtemps que je n'ai rien fait avec COM ou BSTR mais ma suggestion est d'arrêter de traiter BSTR comme quelque chose de spécial. Traitez-les comme un pointeur vers une chaîne terminée par un caractère large à zéro ... si vous le faites, il pourrait être plus facile de les convertir en ANSI. vérifier Eric's Complete Guide to BSTR Semantics ...

Questions connexes