Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

TRAITER STRING VB PAR DLL C/C++ (WIN32)


Information sur la source

Catégorie :API Niveau : Débutant Date de création : 14/03/2005 Date de mise à jour : 02/05/2006 00:45:17 Vu / téléchargé: 6 588 / 476

Note :
10 / 10 - par 3 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (7)
Ajouter un commentaire et/ou une note


Description

Je présente ici une DLL spécialisée VB en ce sens que les String sont envoyées depuis VB en ByRef qui est le mode standard VB.
VB sait aussi passer un char*, on indique ByVal dans la déclaration API des params DLL.
Si on prend char* en param, on ne peut modifier les octets de la String qu'à condition d'avoir préparé un buffer assez large depuis VB (fontion Space()) par exemple.
On ne va donc pas analyser ce cas trivial.

Cas où on reçoit un String en param, il faut prendre *BSTR:
DLL: long __stdcall bnConcat(BSTR *bst1, BSTR *bst2, BSTR *bstRes)
VB : Declare Function bnConcat Lib "d:\bnStrs.dll" (s1 As String, s2 As String, sRes As String) As Long
- "d:\" est juste là pour mes tests, à enlever en prod.
Exemple très simple, on fait strcat de bst1 et bst2 puis résultat dans bstRes, bst1 et bst2 ne seront pas modifiés.
TRES IMPORTANT, bien regarder ce que valent bst1 et bst2 car peut-être non initialisés:

long __stdcall bnConcat(BSTR *bst1, BSTR *bst2, BSTR *bstRes)
{
  char *pmem = 0, *c, *d;
  DWORD len1 = 0, len2 = 0, count = 0;
  if(*bst1) len1 = strlen((char*) *bst1);
  if(*bst2) len2 = strlen((char*) *bst2);
  count = len1 + len2;
  if(!count) goto goResult;
  pmem = (char*) HeapAlloc(GetProcessHeap(), 0, count + 1);
  if(!pmem) {
    count = 0; // pour SysAllocStringByteLen
    goto goResult;
  }
  d = pmem; // initialisation du pointeur de copie
  if(len1) {
    c = (char*) *bst1; // ATTENTION EST DEREF (*) DE BSTR !!!
    while(*d = *c) {d++; c++;} // ici copie en poussant mon pointeur de copie (d)
  }
  if(len2) {
    c = (char*) *bst2; // ATTENTION EST DEREF (*) DE BSTR !!!
    while(*d = *c) {d++; c++;}
  }
goResult: // DOIT ETRE FAIT A TOUT COUP !!!
  if(bstRes) SysFreeString(*bstRes);
  *bstRes = SysAllocStringByteLen(pmem, count); // FAIT UN BSTR POUR VB, si pmem = 0 valable idem
  if(pmem) HeapFree(GetProcessHeap(), 0, pmem);
  return count; // retourne strlen du concat
}

VB: j'ai mis un traitement d'erreurs mais inutile car la dll fait correctement son travail.
Dans tous les cas, si 'if(*bst1) len1 = ...' n'était pas fait, VB ne pourrait pas rattraper l'erreur et plantage complet du prog.
Vous pourrez tester en remettant l'initialisation ou non des String VB, ça marche toujours.

Sub TestConcat()
  Dim R As Long
  Dim st1 As String, st2 As String, stRes As String
  On Error GoTo errConcat
'  st1 = "youpi"
'  st2 = "Hello"
  R = bnConcat(st1, st2, stRes)
  MsgBox stRes, vbInformation, R
  Exit Sub
errConcat:
  MsgBox Err.Description, vbCritical
End Sub

Second cas, retourner un String VB, idem on retourne BSTR:

BSTR __stdcall bnGetWinDir()
{
  char buff[260];
  DWORD len;
  len = GetWindowsDirectory(buff, 260);
  if(!len) buff[0] = 0;
  return SysAllocStringByteLen(buff, len);
}

VB: Declare Function bnGetWinDir Lib "d:\bnStrs.dll" () As String

Sub TesteWindir()
  Dim s As String
  s = bnGetWinDir()
  MsgBox s
End Sub

Si questions, demander.
Code VB dans bnStrs.txt, proj complet de la DLL sur VS 2003.

 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
  •   release
    • bnStrs.dllTélécharger ce fichier [Réservé aux membres club]24 064 octets
    • Test.xlsTélécharger ce fichier [Réservé aux membres club]20 992 octets
  • bnStrs.cppTélécharger ce fichier [Réservé aux membres club]Voir ce fichier1 259 octets
  • bnStrs.defTélécharger ce fichier [Réservé aux membres club]63 octets
  • bnStrs.ncbTélécharger ce fichier [Réservé aux membres club]27 648 octets
  • bnStrs.slnTélécharger ce fichier [Réservé aux membres club]Voir ce fichier901 octets
  • bnStrs.suoTélécharger ce fichier [Réservé aux membres club]8 192 octets
  • bnStrs.txtTélécharger ce fichier [Réservé aux membres club]Voir ce fichier555 octets
  • bnStrs.vcprojTélécharger ce fichier [Réservé aux membres club]3 999 octets

Télécharger le zip

Historique

15 mars 2005 09:14:35 :
Faute de frappe.
26 octobre 2005 16:54:04 :
site
02 mai 2006 00:45:17 :
commentaire

Commentaires et avis

signaler à un administrateur
Commentaire de AlexMAN le 15/03/2005 06:49:33

Y'a pas une erreur de frappe :

#ifdef __cpluplus
{
#endif

?

signaler à un administrateur
Commentaire de BruNews le 15/03/2005 09:15:42 administrateur CS

Faute de frappe corrigée, merci AlexMAN.

signaler à un administrateur
Commentaire de jeralex le 15/03/2005 16:47:26

pour utiliser le code vb, il faut creer quel type de projet car quand je prend le premier (VB6) il y me met une erreur au niveau des declarations.

Erreur de compilation:
Des constantes, chaine de longueur fixe, tableaux, types définis par l'utilisateur et instructions Declare ne sont pas autorisés comme membre Public de module d'objet

Et je te remercie d'avoir pris la peine d'ecrire ce code ca va m'etre tres utile enfin si j'arrive à l'adpater à mes besoins

signaler à un administrateur
Commentaire de BruNews le 15/03/2005 16:55:24 administrateur CS

Les 'Declare Function ...' devraient toujours se trouver dans un module général ce qui les rend accessibles partout, sinon dans un module objet tu dois ajouter 'Private' devant.
Ceci va bon idem dans un module général VBA dans Excel par exemple, c'est d'ailleurs ainsi que je les teste n'ayant plus de VB installé depuis fort longtemps.

signaler à un administrateur
Commentaire de jeralex le 15/03/2005 16:56:20

En faite j'ai trouver

Faut faire dans un module..

signaler à un administrateur
Commentaire de Rudy3212 le 02/09/2005 20:11:15

Superbe Source Bravo et Merci 10/10

signaler à un administrateur
Commentaire de plwwibiza le 07/05/2007 13:29:25

pour vb2005 il semble qu'il faut ecrire la declaration comme cela:

Declare Function bnConcat Lib "d:\bnStrs.dll" (ByRef s1 As String, ByRef s2 As String, ByRef sRes As String) As Long
    Declare Function bnGetWinDir Lib "d:\bnStrs.dll" () As String

mais pour le reste tout reste valable, donc merci pour ce petit exemple ;-)

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Décembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,296 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.