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

EDI Delphi Discussion :

Delphi XE5 - Appel d'une DLL écrite en C avec paramètre par référence


Sujet :

EDI Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2012
    Messages : 18
    Par défaut Delphi XE5 - Appel d'une DLL écrite en C avec paramètre par référence
    Bonjour,

    Depuis plusieurs heures, je n'arrive pas à passer un paramètre et récupérer sa valeur par référence.

    Voici mon code :

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    ////////////////////////////////////////////////////////////////////
     
    procedure Tges0000_ecran.Button1Click(Sender: TObject);
    type
    TGetDLLVersion = procedure (var P1:pansichar); cdecl;
    var
     
           m_DllDataSize:   integer;
        mp_DllData:      Pointer;
        m_DllHandle,d_DllHandle:     THandle;
     
    str1: pansichar;
    VpxDLL:TGetDLLVersion;
     
    begin
     
      m_DllHandle := LoadLibrary('ccvJIL.dll');
      try
        if m_DllHandle = 0 then Abort;
     
            ////Récupération de la version DLL
          @VpxDLL := GetProcAddress(m_DllHandle, 'GetDLLVersion');
     
          if @VpxDLL <> nil then
          begin
     
            //On envoie la transaction sur le terminal
            VpxDLL(str1);
     
            showmessage(str1);
          end;
            /////////////////////////////////////
     
     
     
     
        if m_DllHandle <> 0 then
         FreeLibrary(m_DllHandle);
     
      except
        ShowMessage('An error occoured while loading the dll');
      end;
     
    end;
     
     
    ////////////////////////////////////////////////////////////////////////
    Et voici ce que je sais sur la fonction écrite en C

    Nom : Probleme.jpg
Affichages : 207
Taille : 42,8 Ko


    Merci d'avance de votre aide

  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    remplace ton str1 par un "array[0..23] of Char" comme indiqué par "char Version[24]" !

    voir des AnsiChar si la DLL est en 8bits
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2012
    Messages : 18
    Par défaut
    Double message voir le suivant
    Images attachées Images attachées  

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2012
    Messages : 18
    Par défaut
    [QUOTE=Rinduc;7742120]On avance =)

    J'obtiens le message comme ceci : Nom : message.jpg
Affichages : 189
Taille : 11,1 Ko

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    /////////////////////////////////////////////////
    procedure Tges0000_ecran.Button8Click(Sender: TObject);
    type
    TGetDLLVersion = procedure (var P1: array of char); cdecl;
    var
     
           m_DllDataSize:   integer;
        mp_DllData:      Pointer;
        m_DllHandle,d_DllHandle:     THandle;
     
    str1: array[0..23] of char;
    VpxDLL:TGetDLLVersion;
     
    begin
     
      m_DllHandle := LoadLibrary('ccvJIL.dll');
      try
        if m_DllHandle = 0 then Abort;
     
            ////Récupération de la version DLL
          @VpxDLL := GetProcAddress(m_DllHandle, 'GetDLLVersion');
     
          if @VpxDLL <> nil then
          begin
     
            //On envoie la transaction sur le terminal
            VpxDLL(str1);
     
            showmessage(str1);
          end;
            /////////////////////////////////////
     
     
     
     
        if m_DllHandle <> 0 then
         FreeLibrary(m_DllHandle);
     
      except
        ShowMessage('An error occoured while loading the dll');
      end;
     
    end;
     
    ///////////////////////////////////////////////
    EDIT : Il faut bien mettre des ansichar. Merci beaucoup de votre aide

    Maintenant j'ai essayé de passer les paramètres comme ceci pour la procedure suivante :

    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
    22
    23
    24
    P1:pansichar;
    P2:integer;
    P3:integer;
    P4:pansichar;
    P5:longint;
    P6:array[0..255] of ansichar;
    P7:array[0..11] of ansichar;
    P8:array[0..255] of ansichar;
    P9:array[0..255] of ansichar;
    P10:pansichar;
    P11:integer;
    P12:array[0..6] of ansichar;
    P13:array[0..6] of ansichar;
    P14:integer;
    P15:integer;
    P16:integer;
    P17:array[0..6] of ansichar;
    P18:array[0..8] of ansichar;
    P19:array[0..11] of ansichar;
    P20:pansichar;
    P21:integer;
    P22:longint;
    P23:integer;
    P24:array[0..255] of ansichar;
    Paramètres de la DLL écrite en C : Nom : DLL.jpg
Affichages : 266
Taille : 341,9 Ko

    J'obtiens l'erreur suivant : Nom : Violation.jpg
Affichages : 211
Taille : 28,9 Ko

    Avez-vous une idée ?

    Désolé mais j'ai passé tout la journée hier à essayer ...

  5. #5
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    attention ! un "array of char" n'est pas un "array[0..x] of char" !!!! le premier est dynamique alors que le second est statique !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    type
      TVersion = array[0..23] of AnsiChar;
      GetDLLVersion = procedure(var Version: TVersion); cdecl;
    ensuite le principe de traduction C -> Delphi est relativement simple:

    unsigned char, char => AnsiChar
    int => Integer
    long => LongInt (souvent identique à Int)

    char peut aussi se traduire en Byte selon le cas, C ne fait pas la différence entre les deux

    ensuite "*" c'est un pointeur, donc char * => ^Char = PChar

    MAIS en Pascal on peut passer les paramètres par adresse avec le mot clé VAR, du coup ce n'est plus un pointer: "function f1(i: PInteger)" et "function f2(var i:Integer)" donne exactement la même chose.

    D'autre part, tous les paramètres sont en "out", c'est à dire que la fonction va écrire dans le paramètre qui DOIT exister, on ne donne donc pas un PInteger, mais l'adresse d'un Integer, tout comme Version demande un pointeur sur 24 caractères et non un PChar vide.

    dernier point, en C un tableau est TOUJOURS un pointeur, donc tous les paramètres sont en fait par adresse.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    function GetLastTransactionDetail(
      var TransactionType: ??? (il manque la taille),
      var pCurrencyCode: Integer;
      var pTransactionResultCode: ???,
      var AuthtorizationResultText: TAuthtorizationResultText, // = array[0..255] of Char;
      ... 
    ) cdecl;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2012
    Messages : 18
    Par défaut
    Merci pour les réponses mais j'ai encore quelques questions.

    comment faire pour déclarer en statique dans mon TGetLastTransactionDetail car il met l'erreur suivante : "E2029 'OF' attendu(e) mais '[' trouvé(e)" lorsque je déclare comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    
    TGetLastTransactionDetail = procedure (var P1:pansichar;var P2:integer;var P3:integer;var P4:pchar;var P5:longint;var P6:array[0..255] of ansichar;var P7:array of ansichar;
    var P8:array of ansichar;var P9:array of ansichar;var P10:pansichar;var P11:integer;var P12:array of ansichar;var P13:array of ansichar;var P14:integer;
    var P15:integer;var P16:integer;var P17:array of ansichar;var P18:array of ansichar;var P19:array of ansichar;var P20:pansichar;var P21:integer;var P22:longint;
    var P23:integer;var P24:array of ansichar
    ); cdecl;
    ensuite "*" c'est un pointeur, donc char * => ^Char = PChar --> ça veut dire quoi ? Que unsigned char* je dois le mettre en pchar ?


    Mais si c'est int* je dois laisser en int c'est bien juste ?

    Je vais essayer tout ça lorsque j'aurai une réponse

    Merci beaucoup.

Discussions similaires

  1. [Débutant] Appel d'une procédure insert ou update avec paramètres
    Par Bakkach dans le forum VB.NET
    Réponses: 17
    Dernier message: 18/04/2013, 14h44
  2. Appel d'une DLL écrite en C# en Delphi
    Par develpp1 dans le forum Débuter
    Réponses: 5
    Dernier message: 18/06/2012, 16h01
  3. Appeler une Dll écrite en .NET avec Forms
    Par titan_33 dans le forum Forms
    Réponses: 0
    Dernier message: 22/09/2008, 17h55
  4. [VC++] Utilisation d'une DLL écrite en C++ avec mingw.
    Par swirtel dans le forum Visual C++
    Réponses: 1
    Dernier message: 20/06/2007, 10h42
  5. Réponses: 1
    Dernier message: 11/04/2007, 11h45

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