OVH Cloud OVH Cloud

Gestion des chaines dans une DLL C++ Utilisable dans VB

2 réponses
Avatar
cheickna Traoré
Bonjour à tous,

Je suis confus à propos de l'utilisation des chaines dans une Dll C++. J'ai
crée une Dll en Visual C++ en utilisant comme il faut le mot clé __stdcall
qui précède les noms des fonctions. Elle fonctionne aussi bien si le client
est C++ ou VB, mais dans les nombreuses documentations que j'ai lues il est
toujours mentionné que pour le traitement des chaines dans VB il est
nécessaire d'utiliser le type BSTR dans la Dll C++. Donc dans ma fonction de
la Dll le protype est le suivant :
extern "C" BSTR __stdcall GetMD5String(BSTR szString);
Donc en VB si j'essaye de récuperer la chaine retournée par cette fonction
de la dll comme ceci :
Dim MyString as string
MyString = GetMD5String("Toto");
MyString contiendra la valeur de retour MAIS au format unicode. Je suis
obligé dans mon code de convertir explicitement cette valeur à l'aide de la
fonction strconv comme suit : StrConv(MyString , vbFromUnicode).

Pourquoi si j'utilise des API Windows en VB je n'affectue pas cette
conversion ? Il me suffit de de déclarer des variables en VB en spécifiant
leur taille puis de les passer au API Windows. Ces API utilisent simplement
le type LPSTR ou LPCSTR dans leur prototype mais pas BSTR.

Quelqu'un pourra t-il me donner quelques explications que j'ai loupées dans
mes lectures ?


Merci d'avance

2 réponses

Avatar
Zoury
Salut Cheickna! :O)

Pourquoi si j'utilise des API Windows en VB je n'affectue pas cette
conversion ? Il me suffit de de déclarer des variables en VB en spécifiant
leur taille puis de les passer au API Windows. Ces API utilisent


simplement
le type LPSTR ou LPCSTR dans leur prototype mais pas BSTR.

Quelqu'un pourra t-il me donner quelques explications que j'ai loupées


dans
mes lectures ?



t'as lu ce document?

Win 32 APi Programming With VB 6 - Chapter 6: Strings
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnw32dev/html/ora_apiprog6_topic1.asp

--
Cordialement
Yanick Lefebvre - MVP pour Visual Basic
http://faq.vb.free.fr/?rubrique=0 - http://www.mvps.org/vbnet/
http://www.mentalis.org/agnet/apiguide.shtml - http://www.mztools.com/

Merci de poster les réponses au groupe afin d'en faire profiter à tous
Avatar
Zoury
Resalut Cheickna! :O)

je ne sais pas si tu l'as lu, mais pour ceux qui l'ont lu et ne comprenne
toujours pas ce qui se passe, voici une p'tite explication..

le document spécifie pleins de choses très intéressantes concernant la
structure BSTR... j'aimerais attiré votre attention sur trois d'entre
elles.. :

- The BSTR is the actual pointer variable. It has size 32 bits, like all
pointers, and points to a Unicode character array. Thus, a Unicode character
array and a BSTR are not the same thing. It is correct to refer to a BSTR as
a string (or VB string) but, unfortunately, the Unicode character array is
also often called a string! Hence, we will not refer to a BSTR simply as a
string--we will refer to it by its unequivocal name--BSTR.

- Again, the pointer points to the beginning of the character array, not to
the 4-byte length field that precedes the array. As we will see, this is
critical to interpreting a BSTR as a VC++-style string.

- This makes it clear why BSTR's are null terminated. A BSTR with no
embedded nulls is also an LPWSTR. We will discuss C++ strings in a moment.


Donc une BSTR n'est rien d'autre qu'un pointeur vers un tableau d'octet..

Maintenant VB conserve une BSTR de type unicode en mémoire et créer un copie
de type ASCII lorsque l'utilisateur travaille avec la chaine... Lorsque l'on
passe une chaine à une fonction API, le pointeur envoyé à la fonction pointe
au début du tableau de caractères qui correspond donc à un LPSTR/LPCSTR ou
un LPWSTR/LPCWSTR. Si tu passes la chaine de cette façon [ByVal sMaChaine],
VB créer le BSTR ASCII en mémoire et te renvoi le LPSTR/LPCSTR. Si,
parcontre, tu passes la chaine comme ceci [ByVal StrPtr(sMaChaine)], VB
renvoit automatiquement le LPWSTR/LPCWSTR existant en mémoire, ce qui est
plus rapide évidemment... ;O)

Voici un exemple :
'***
Option Explicit

Private Declare Sub CopyMemory _
Lib "kernel32" _
Alias "RtlMoveMemory" _
( _
ByRef pDst As Any, _
ByRef pSrc As Any, _
ByVal ByteLen As Long _
)

Private Sub Main()

Dim s As String
Dim i As Long
Dim byASCII() As Byte
Dim byUNICODE() As Byte

s = "Salut"

' On copie la chaine ASCII dans notre tableau ASCII
ReDim byASCII(Len(s) - 1) As Byte
Call CopyMemory(byASCII(0), ByVal s, Len(s))
Debug.Print "ASCII :"
For i = 0 To UBound(byASCII)
Debug.Print " byte " & i & " : " & byASCII(i)
Next i

' On copie la chaine UNICODE dans notre tableau UNICODE
ReDim byUNICODE(LenB(s) - 1) As Byte
Call CopyMemory(byUNICODE(0), ByVal StrPtr(s), LenB(s))
Debug.Print "UNICODE :"
For i = 0 To UBound(byUNICODE)
Debug.Print " byte " & i & " : " & byUNICODE(i)
Next i

End Sub
'***

Karl E. Peterson à d'ailleurs fait une comparaison du temps d'exécution
entre la version ASCII et UNICODE d'un fonction API dans son article sur les
Benchmarks..
http://www.mvps.org/vb/tips/benchmarks.htm

--
Cordialement
Yanick Lefebvre - MVP pour Visual Basic
http://faq.vb.free.fr/?rubrique=0 - http://www.mvps.org/vbnet/
http://www.mentalis.org/agnet/apiguide.shtml - http://www.mztools.com/

Merci de poster les réponses au groupe afin d'en faire profiter à tous
"Zoury" <yanick_lefebvre at hotmail dot com> wrote in message
news:eMFKlq%
Salut Cheickna! :O)

> Pourquoi si j'utilise des API Windows en VB je n'affectue pas cette
> conversion ? Il me suffit de de déclarer des variables en VB en


spécifiant
> leur taille puis de les passer au API Windows. Ces API utilisent
simplement
> le type LPSTR ou LPCSTR dans leur prototype mais pas BSTR.
>
> Quelqu'un pourra t-il me donner quelques explications que j'ai loupées
dans
> mes lectures ?

t'as lu ce document?

Win 32 APi Programming With VB 6 - Chapter 6: Strings



http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnw32dev/html/ora_apiprog6_topic1.asp

--
Cordialement
Yanick Lefebvre - MVP pour Visual Basic
http://faq.vb.free.fr/?rubrique=0 - http://www.mvps.org/vbnet/
http://www.mentalis.org/agnet/apiguide.shtml - http://www.mztools.com/

Merci de poster les réponses au groupe afin d'en faire profiter à tous