IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Problème de mémoire lors de l'appel d'une DLL C++


Sujet :

Delphi

  1. #1
    Membre régulier
    Femme Profil pro
    Inscrit en
    Avril 2007
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 209
    Points : 93
    Points
    93
    Par défaut Problème de mémoire lors de l'appel d'une DLL C++
    Bonjour,

    J'utilise une application Delphi 7 pour appeler une DLL qui a été réalisée en C++ (Je ne possède pas les sources de cette DLL, uniquement les en-têtes).

    La dll me fournit les éléments suivant :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef struct{
    	UINT instrNumber;
    	USHORT bond;
    	BSTR dongleAddress;
    	BSTR macAddress;
    	BSTR name;
    	ConnectionState state;
    	TypeDeviceBluetooth typeDeviceBt;
    	TypeInstrument type;
    	USHORT writeHandle;
    }BTInstrument;
     
    extern "C" MADLL_API UINT __stdcall getNumberInstrFound(UINT dongleNumber);
    extern "C" MADLL_API bool __stdcall getFoundBTInstr(UINT dongleNumber, UINT indexInstr, BTInstrument* instr);

    Dans mon application Delphi, j'ai redéfini les éléments suivants :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Type
    TBTInstrument = Record
          instrNumber : Cardinal; {UINT}
          bond : Word; {USHORT}
          dongleAddress : pWideChar;{BSTR}
          macAddress : pWideChar;
          name  : pWideChar;
          state : TConnectionState;
          typeDeviceBt : TTypeDeviceBluetooth;
          typeI : TTypeInstrument;
          writeHandle : Word;
        End;
     
     
    function getNumberInstrFound(dongleNumber: Cardinal): Cardinal stdcall;
    Procedure getFoundBTInstr(dongleNumber: Cardinal;
                              indexInstr: Cardinal;
                              Out instr: TBTInstrument) stdcall;
     
    function getNumberInstrFound; stdcall;external 'MADLLdll.DLL';
    Procedure getFoundBTInstr; stdcall;external 'MADLLdll.DLL';
    Pour tester le tout, j'ai fait l'appel suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Procedure Test;
    Var
    	IInstruments : Integer;
    	CurrentInstr : TBTInstrument;
     
    Begin
    	NbInstr:=getNumberInstrFound(0);
     
    	For IInstruments:=0 To NbInstr-1 Do
    	Begin
    		getFoundBTInstr(0,IInstruments,CurrentInstr)
    		ShowMessage(CurrentInstr.macAddress);
    	End;
    End;
    La valeur de NbInstr est à 3, ce qui est étrange c'est que lors de l'appel à "getFoundBTInstr", ma variable "IInstruments" qui est ma variable de boucle, se réinitialise à 0, je me retrouve donc avec une boucle sans fin. J'ai essayé en utilisant une variable intermédiaire comme paramètre, rien n'y fait. on dirait que l'appel à "getFoundBTInstr" empiète sur des plages mémoire de mon application et écrase certaines variables que j'utilise. Est-ce possible? comment protéger un environnement mémoire, ou comment résoudre ce genre de problème?

    Merci d'avance.

  2. #2
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    peut etre que ce n'est pas la bonne convention d'appel. "Extern C" correspond à stdcall ou cdecl ?
    Citation Envoyé par Aide delphi : Conventions d'appel
    Directive Ordre des paramètres Nettoyage Transfert des paramètres dans les registres*?
    cdecl De droite à gauche Appelant Non
    stdcall De droite à gauche Routine Non

  3. #3
    Membre régulier
    Femme Profil pro
    Inscrit en
    Avril 2007
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 209
    Points : 93
    Points
    93
    Par défaut
    Salut Guillemouze,

    Merci pour ta réponse.

    Après vérification auprès de l'éditeur, la DLL doit bien être appelée en "stdcall". de plus j'ai fait un essai avec "cdecl" et c'est toutes mes autres procédures ou fonctions venant de cette DLL qui plantent complètement.

  4. #4
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    je crois que c'est un problème d'alignement de ton record.
    les types énumérés sont sur 4 octets en C++, alors qu'ils ont la taille minimale possible en fonction du nombre d’éléments dans delphi.
    Il faut juste mettre ceci dans ton code, pour que tes enums soit aligné sur 4 octets : {$Z4}, avant les déclarations de tes type énumérés TConnectionState, TTypeDeviceBluetooth, TTypeInstrument
    par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {$Z4}
    Type
      TConnectionState = (csDisconnected, csConnecting, csConnected);
      ...
    {$Z1}// facultatif, tu peux rester en Z4 ce n'est pas gênant
    Peut etre aussi qu'il faudrait que tu convertisse ton record en packed record, mais je ne suis pas sur que ça ait un impact.

  5. #5
    Membre régulier
    Femme Profil pro
    Inscrit en
    Avril 2007
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 209
    Points : 93
    Points
    93
    Par défaut
    Wo magnifique, Avec les directives de compilation pour les types énumérés, ça fonctionne maintenant parfaitement.

    Merci beaucoup pour ta réponse et pour ton aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur lors de l'appel d'une DLL en C depuis Java
    Par rinuom dans le forum Général Java
    Réponses: 1
    Dernier message: 30/04/2012, 19h23
  2. Problème de timeout lors de l'appel d'une méthode Stop
    Par drieu13 dans le forum API standards et tierces
    Réponses: 0
    Dernier message: 12/04/2012, 16h53
  3. Réponses: 7
    Dernier message: 05/06/2008, 14h37
  4. Réponses: 8
    Dernier message: 17/09/2007, 20h16
  5. Erreur lors de l'appel d'une DLL créée avec Visual
    Par WELCOMSMAIL dans le forum C++Builder
    Réponses: 6
    Dernier message: 06/09/2006, 15h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo