Gestion des chaines dans une DLL C++ Utilisable dans VB
2 réponses
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 ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
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
Merci de poster les réponses au groupe afin d'en faire profiter à tous
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
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
Merci de poster les réponses au groupe afin d'en faire profiter à tous
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
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
Merci de poster les réponses au groupe afin d'en faire profiter à tous
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
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%230DHA.1188@TK2MSFTNGP11.phx.gbl...
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
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
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