Appel de DLL à partir de VB: problème d'arguments

Résolu
Taoufik77 Messages postés 14 Date d'inscription dimanche 17 octobre 2004 Statut Membre Dernière intervention 3 novembre 2004 - 28 oct. 2004 à 09:24
Taoufik77 Messages postés 14 Date d'inscription dimanche 17 octobre 2004 Statut Membre Dernière intervention 3 novembre 2004 - 28 oct. 2004 à 12:21
Bonjour tout le monde,

je développe une appli VB qui fait appel à une fonction dll écrite en visual C++. lorsque je fais le debugging, je me rends -compte que les paramètres reçus par la fonction dll ne sont pas du tout les mêmes que ceux envoyés par l'appli VB.

Prototype de la fonction DLL:
char __stdcall Test(unsigned char param1, unsigned char param2, unsigned char param3);

Déclaration de la fonction en VB:
Private Declare Function Test Lib _
"Chemin de la dll" _
(ByRef param1 As Byte, ByRef param2 As Byte, ByRef param3 As Byte) As Byte

Ce problème ne se pose pas lorsque ma fonction prends uniquement un seulk argument.

Il s'agit peut-être d'une différence de taille de variable entre les deux langages. Il parait qu'enVB, une variable est mise sur 4 octes même s'il s'agit d'un Byte (1 octet) ou d'un Integer (2octets)

J'ai essayé contourner cette différence en déclarant des long (4 octets) dans la fonction dll:
Prototype de la fonction DLL:
char __stdcall Test(long param1, long param2, long param3);

mais le debegging révèle que les paramètres reçues sont érronés dans ce cas là aussi.

Il y a des réglages qu'on peut faire lors de l'édition de la dll sur Vc++ en ce qui concerne l'alignement des structures :
(Project->Settings->C/C++ et dans le champ "category" choisir "Code generation" puis dans le champ "Struct member alignment" choisir "4 Bytes" )
mais ça ne change pas grand chose

Je vous remercie de votre temps
:o)
touf

5 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
28 oct. 2004 à 11:20
typedef struct {
unsigned char Etat;
unsigned char Mode;
unsigned short NumberPulse;
unsigned short Unite;
unsigned char EnvoiAuto;
unsigned char ActiveEtat;
} CONFIG_ENTREE, *LPCONFIG_ENTREE;

faut prendre un pointeur de struct en param DLL sinon bonjour les perfs, sera trop long a PUSHer chaque param.

Faut modif ta DLL ainsi (et le code interne bien entendu):
char __stdcall TestParam(unsigned char numEntree, LPCONFIG_ENTREE pce);

ciao...
BruNews, MVP VC++
3
Taoufik77 Messages postés 14 Date d'inscription dimanche 17 octobre 2004 Statut Membre Dernière intervention 3 novembre 2004
28 oct. 2004 à 12:21
Et pour revenir au problème de décalage, il faut :

d'abord faire le bon mapping entre les types C++ et les types VB (exemple: unsigned char<->Byte, unsigned short <-> Integer ).

Après il faut définir le bon "nom décoré (decorated name) de la fonction appelé à partir de VB et ce dans le fichier .DEF du projet de la dll.

Le "nom décoré" se trouve dans le fichier .COD du projet de la dll suivi de la mention "PROC NEAR"
3
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
28 oct. 2004 à 10:06
Salut,

y a un gros malaise dans ton affaire, faudra reviser les fondamentaux de la prog.

Quel que soit le langage, chaque param fait 4 octets pour un prog 32 bits, que soit en C++ ou en Z-- et quelle que soit la declaration des params de la dll. S'il n'en etait pas ainsi on aurait un desalignement de la stack et serait crash complet a tout coup.

char __stdcall Test(unsigned char param1, ....);
param1 est PUSHe en 4 octets, le compilo POPera aussi 4 octets en sortie bien qu'il ne lira que l'octet de poids faible. VB PUSH egalement 4 octets comme il se doit. Le seul prob est la declaration ByRef au lieu de ByVal, VB t'envoie l'adresse (pointeur) au lieu de la valeur.

ciao...
BruNews, MVP VC++
0
Taoufik77 Messages postés 14 Date d'inscription dimanche 17 octobre 2004 Statut Membre Dernière intervention 3 novembre 2004
28 oct. 2004 à 10:34
Salut, et merci pour ta réponse rapide.

En effet, j'ai omis de laisser le ByRef . C'est que, au départ mon objectif était de passer un type prédéfini en paramètre (et donc obligé d'utiliser ByRef)
mon type défini dans la dll est le suivant:

typedef struct
{
unsigned char Etat;
unsigned char Mode;
unsigned short NumberPulse;
unsigned short Unite;
unsigned char EnvoiAuto;
unsigned char ActiveEtat;
} CONFIG_ENTREE;

et en VB:

Private Type CONFIG_ENTREE
Etat As Byte
Mode As Byte
NumberPulse As Integer
Unite As Integer
EnvoiAuto As Byte
ActiveEtat As Byte
End Type

comme tu peux le constater j'ai fait le mapping de type de données entre C++ et VB: unsigned char<->Byte et unsigned short<->Integer

le prototype de la fonction dll:
char __stdcall TestParam(unsigned char numEntree, CONFIG_ENTREE param1);

et la déclaration VB:
Private Declare Function TestParam Lib _
"le chemin de ma dll" _
(ByVal numEntree As Byte, param1 As CONFIG_ENTREE) As Byte

Seulement, le 1er paraètre (numEntree) est corectement reçu, le second (type prédéfini) est erroné

J'espère que tu pourras m'éclairer
Merci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Taoufik77 Messages postés 14 Date d'inscription dimanche 17 octobre 2004 Statut Membre Dernière intervention 3 novembre 2004
28 oct. 2004 à 12:15
Merci BruNews.
Tu ne peux pas imaginer combien tu m'as aidé

:o)
0
Rejoignez-nous