Pb de retour d'une chaine de carac. à partir d'une dll C++ sous Windows Seven 64

Signaler
Messages postés
4
Date d'inscription
jeudi 16 novembre 2000
Statut
Membre
Dernière intervention
14 mars 2010
-
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
-
Bonjour,

Voici un point de blocage sur lequel je bute depuis pas mal de temps. Merci à ceux qui pourront m'aider.

J'ai développé un soft qui fonctionne sur Excel (VBA) et qui fait appel à des dll (codées en Visual C++ 6.0) pour effectuer des calculs. Tout fonctionne sans pb avec une plate forme 32 bits.

Sous Win Seven 64 bits, rien ne fonctionne en l'état, j'ai supposé une incompatibilité dans le codage des variables utilisées. J'ai recréé mes dll en utilisant Visual C++ Express 2008 (qui au passage ne me permet pas de compiler en natif pour les plate-formes 64 bits, mais peu importe).

Au final, les fonctions de mes dll qui retournent des valeurs numériques à mon code VBA fonctionnent sans pb.

Ca se complique avec les fonctions qui retournent des chaînes de caractères. A chaque retour d'une de ces fonctions, j'obtiens un plantage d'Excel qui se ferme de façon intempestive.

Initialement j'utilisais le code suivant :

Dans la DLL:

- Fichier d'entête:
#ifdef MADLL_EXPORTS
#define MADLL_API __declspec(dllexport)
#else
#define MADLL_API __declspec(dllimport)
#endif

- Fichier code:
LPSTR __stdcall RetourChaineParFonction(){
LPSTR* t = new LPSTR[5];
t[0] = "Texte par fonction";
return t[0];
}
void __stdcall RetourChaineParReference(char* ts){
strcpy(ts, "Texte par référence");
}

Dans la macro VBA:
Declare Function RetourChaineParFonction Lib "C:\Chemin\MaDll" () As String
Declare Sub RetourChaineParReference Lib "C:\Chemin\MaDll" (ByRef t As String, ByVal i As Long)

Public Sub RetourTexte()
Dim str() As String, i As Long, NbTxt As Long

str(1) = String(255, vbNullChar) 'allocation d'espace mémoire
str(1) = RetourChaineParFonction 'Provoque un plantage d'Excel
RetourChaineParReference str(1), 0 'Provoque un plantage d'Excel
End Sub


Bref, Excel plante à chaque tentative de récupération de ma chaine.
J'ajoute que j'ai également essayé d'utiliser le format LPCSTR, BSTR, sans plus de succès (le format LPTSTR bloque même à la compilation).

Enfin, je précise que ça marche sans pb sur une plate forme 32 bits.

Merci d'avance à tous ceux qui peuvent m'apporter leur aide.

7 réponses

Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
Tu effaces tout cela, il n'y a strictement rien à conserver.

Pas de 'new' ou autres biniouteries du C++ (imagine la tronche de VBA au moment de désallouer...), la DLL doit etre codée et compilée en mode C et n'utiliser exclusivement que l'API pour les alllocs (SysAllocSring[xxx] pour les string VB).

Reporte toi aux nombreux exemples que j'ai fait de DLLs pour VB/VBA, sur cppfrance comme sur vbfrance.

ciao...
BruNews, MVP VC++
Messages postés
15026
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
7 mai 2021
94
Hello,
LPSTR* t = new LPSTR[5];
t[0] = "Texte par fonction";

A mon avis, il y a plus que 5 caractères...

@+
Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Messages postés
4
Date d'inscription
jeudi 16 novembre 2000
Statut
Membre
Dernière intervention
14 mars 2010

Pardon, il s'agit d'une faute de frappe.
J'avais bien mis :
LPSTR* t = new LPSTR[50];

mais ça ne fonctonne pas mieux.

Merci de ton aide
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Bonjour,

LPSTR* t new LPSTR[50]; alloue 50 LPSTR donc 50 char * et pas 50 char comme tu as l'air de le penser (t est un char**). Donc en faisant t[0] "Texte par fonction"; t[0] contient l'addresse de "Texte par fonction" dans ta dll, il n'est donc pas très étonnant que tu ne récupères pas ce que tu veux dans ton code VBA.

Peut-être pourrais-tu essayer :

LPSTR* t = new LPSTR[50];
t[0] = new char[50];
strcpy( t[0], "Texte par fonction" );

ou bien si tu n'as besoin que d'une chaîne :

LPSTR t = new char[50];
strcpy( t, "Texte par fonction" );
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
30
Pourquoi cette insistance sur 'new' ???

ciao...
BruNews, MVP VC++
Messages postés
4
Date d'inscription
jeudi 16 novembre 2000
Statut
Membre
Dernière intervention
14 mars 2010

Bonjour ed73 et merci de ton aide

J'ai modifié mon code suivant tes conseils, mais j'obtiens toujours un plantage d'Excel dès que la fonction de ma dll retourne la chaine.
Je précise que la chaine de caractère est correctement écrite dans le tableau, je la visualise sans pb en mode debug. C'est après le "return" que ça plante.

Une autre idée ?
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Désolé que ça ne fonctionne pas. Une autre idée serait d'allouer ta chaîne de caractères dans VB et de la passer à ta dll en paramètre, la fonction se chargeant de lui affecter les données.