Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

DLL et passage de structure

3 réponses
Avatar
Vince
Bonjour,

je dois envoyer des données issues d'une application ecrite en VB6 a une Dll
MFC. Pour ca j''utilise la structure VB suivante :

Private Type TDATAGLDS
CardID As String * 17
NoIssuer As Integer
Conf As Byte
Category As Byte
Resto As Byte
Luggage As Byte
CloakRoom As Byte
Country As String * 24
LastName As String * 29
FirstName As String * 29
Company As String * 29
NbClothes As Byte
CKRoomID1 As Integer
CKRoomID2 As Integer
CKRoomID3 As Integer
CKRoomID4 As Integer
NbLuggage As Byte
LuggageID1 As Integer
LuggageID2 As Integer
LuggageID3 As Integer
LuggageID4 As Integer
BarCode39 As String * 128
PdfPath As String * 255
End Type

ce qui donne du coté de la DLL :

#pragma pack( push, 4)
typedef struct
{
BYTE CardID[17]; // "ID card"
BYTE NoIssuer[2]; // Numero Identifiant
BYTE Conf; // Droits pour conference
BYTE Category; // Categorie (Delegate, Press, Speaker)
BYTE Resto; // Droits pour Resto
BYTE Luggage; // Malette
BYTE CloakRoom; // Vestiaire
BYTE Country[24]; // Pays
BYTE LastName[29]; // Nom
BYTE FirstName[29]; // Prenom
BYTE Company[29]; // Société
BYTE NbClothes; // Nb Vetements
BYTE CKRoomID1[2]; // Vetement ID1
BYTE CKRoomID2[2]; // Vetement ID2
BYTE CKRoomID3[2]; // Vetement ID3
BYTE CKRoomID4[2]; // Vetement ID4
BYTE NbLuggage; // Nb Bagages
BYTE LuggageID1[2]; // Bagage ID1
BYTE LuggageID2[2]; // Bagage ID2
BYTE LuggageID3[2]; // Bagage ID3
BYTE LuggageID4[2]; // Bagage ID4
BYTE BarCode39[128]; // Valeurs du BarCode 39
BYTE PdfPath[255]; // Chemin du bitmap PDF
}DATAGLDS;
#pragma pack( pop )



et la fonction de la dll ci dessous :


int __stdcall TransferData(DATAGLDS * pData){

CString csTmp;
csTmp.Format( _T("CardID=%s\nLast Name=%s\nFirst Name=%s\nConf=0x%x\n"),
pData->CardID,
pData->LastName,
pData->FirstName,
pData->Conf);


AfxMessageBox(csTmp);
}

que je declare comme ca en VB : Private Declare Function TransferData Lib
"DataGLDS.dll" (data As TDATAGLDS) As Long

Mon souci est que losque je fais ca :

Dim data As TDATAGLDS

data.CardID = "Test"
data.LastName = "SMITH"
data.FirstName = "John"

TransferData data

Et bien j'ai bien le MessageBox de la Dll qui s'affiche mais qui contient
une chaine vide pour le champ LastName.



Please Help

3 réponses

Avatar
Patrick Philippot
Vince wrote:
Et bien j'ai bien le MessageBox de la Dll qui s'affiche mais qui
contient une chaine vide pour le champ LastName.



Bonjour,

Je crois qu'il faudrait d'abord faire un peu de ménage dans vos
déclarations. Comme les structures sont alignées à 4 octets (ce dont
vous tenez compte avec le pragma pack(4)), cela ne sert à rien de
déclarer des valeurs de type BYTE, sinon à créer de la confusion.
Déclarez directement des Long(s) pour les entiers. Idem côté C++. Les
chaînes de caractères devraient être déclarées "char LastName[29];".
Mais ce n'est pas le vrai problème.

Plus fondamentalement: les chaînes de caractères VB de longueur fixe ne
sont pas terminées par des 0. C'est un miracle si votre DLL ne se plante
pas. Soit vous ajoutez le 0 côté VB, soit vous copiez les data depuis la
structure dans un buffer intermédiaire avec strncpy et vous ajoutez le
0. Puis vous utilisez ce buffer dans la méthode Format.

Voir l'article de la doc VB 6 appelé "Passing User-Defined Types to a
DLL Procedure". Plus spécifiquement les 2 derniers paragraphes qui sont
très clairs sur l'erreur commise dans votre code.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Vince
Ok merci je vais explorer cette piste par contre j'ai encore queleques
questions.
Est ce que ca sert a quelque chose que j'utilise la convention __stdcall ou
est ce superflue ?
Ma deuxieme question concerne le debug de ma Dll, est il possible de voir ce
qu'elle recoit de la
de l'appli VB ?


"Patrick Philippot" a écrit dans le message
de news:
Vince wrote:
Et bien j'ai bien le MessageBox de la Dll qui s'affiche mais qui
contient une chaine vide pour le champ LastName.



Bonjour,

Je crois qu'il faudrait d'abord faire un peu de ménage dans vos
déclarations. Comme les structures sont alignées à 4 octets (ce dont vous
tenez compte avec le pragma pack(4)), cela ne sert à rien de déclarer des
valeurs de type BYTE, sinon à créer de la confusion. Déclarez directement
des Long(s) pour les entiers. Idem côté C++. Les chaînes de caractères
devraient être déclarées "char LastName[29];". Mais ce n'est pas le vrai
problème.

Plus fondamentalement: les chaînes de caractères VB de longueur fixe ne
sont pas terminées par des 0. C'est un miracle si votre DLL ne se plante
pas. Soit vous ajoutez le 0 côté VB, soit vous copiez les data depuis la
structure dans un buffer intermédiaire avec strncpy et vous ajoutez le 0.
Puis vous utilisez ce buffer dans la méthode Format.

Voir l'article de la doc VB 6 appelé "Passing User-Defined Types to a DLL
Procedure". Plus spécifiquement les 2 derniers paragraphes qui sont très
clairs sur l'erreur commise dans votre code.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr



Avatar
Patrick Philippot
Vince wrote:

Ok merci je vais explorer cette piste



Ce n'est pas une piste. C'est la réponse :-) .

Est ce que ca sert a quelque chose que j'utilise la convention
__stdcall ou est ce superflu ?



Bien sûr que non, ce n'est pas surperflu. Pour qu'une fonction dans une
DLL puisse être appelée par un code écrit dans un langage différent, il
faut bien qu'appelant et appelé se mettent d'accord sur une convention
d'appel commune. Sinon, c'est le crash assuré. Cette convention d'appel
commune est spécifiée par __stdcall.

Ma deuxieme question concerne le debug de ma Dll, est il possible de
voir ce qu'elle recoit de l'appli VB ?



Oui, bien sûr. Pour déboguer une DLL, il suffit de spécifier dans les
propriétés du projet (DLL), quel exécutable doit être lancé quand on
démarre une session de déboguage de la DLL (cet exécutable utilisant
bien sûr la DLL). Si vous êtes en VS6: Project | Settings | Debug |
Executable for debug session. Quand vous appuyez sur F5, VS lance le
programme indiqué et quand un appel est fait depuis ce programme client
sur une des fonctions exportées par la DLL, les points d'arrêts
positionnés dans le code de la DLL sont pris en compte et vous pouvez la
déboguer comme n'importe quel autre programme.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr