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 :

Utiliser des fonctions d'une DLL C++


Sujet :

Delphi

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Utiliser des fonctions d'une DLL C++
    Bonjour,

    Dans mon projet Delphi win32, je dois utiliser des fonctions provenant d'une dll c++ (libsvm). Cette librairie a été compilée avec l'outil c/c++ Builder de Borland avec les fichiers source *.cpp, *.h.

    Pour une fonction c qui renvoie une chaine de caractères:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char * PrintHelloyou();
    J'arrive à récupérer directement la chaîne de caractères dans delphi. C'était assez fastidieux quand même ^^.

    Maintenant je dois utiliser une autre fonction de la dll, qui renvoie un pointeur sur une structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct svm_model *svm_train(const struct svm_problem *prob,  struct svm_parameter *param);
    et c'est là que ca coince . Lors de l'execution en mode "pas à pas", le programme n'arrive pas à trouver la fonction svm_train de la dll. Pourtant j'ai utilisé le même procédé que pour la fonction PrintHelloYou();

    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
     
      //test svm_train
      Handle := LoadLibrary('myDLL.dll');
      if Handle <> 0 then
        begin
          pointeur_tmp := GetProcAddress(Handle, '_svm_train');
        if pointeur_tmp <> nil then
             begin
           showmessage('debut de l''entrainement');
         // my_model := _svm_train(myPsvm_prob, UPsvm_parameter);
           showmessage('fin de l''entrainement');
           end;
     
        end;
        FreeLibrary(Handle);
     
       // Test PrintHello
        Handle := LoadLibrary('myDLL.dll');
        if Handle <> 0 then
        begin
          pointeur_tmp2 := GetProcAddress(Handle, '_PrintHelloYou');
        if pointeur_tmp2 <> nil then
             begin
           showmessage('debut de PrintHello');
           myPCHAR := _PrintHelloYou;
     
           showmessage('fin de PrintHello; message : '+Pansistring(MyPchar));
           end;
     
        end;
        FreeLibrary(Handle);
    Ici:
    pointeur_tmp2 , pointeur_tmp sont des pointeurs de type pointer

    pointeur_tmp n'est pas egal à nil, alors que pointeur_tmp2 = nil.

    Donc j'en deduit que le programme n'a pas trouver l'adresse de la fonction svm_train de la dll.

    Quelqu'un aurait une idée?
    Merci

    Si ca peut aider, les codes sources* h, *PAS:

    Wrapper C ::
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    unit SVM;
    interface
    uses Sysutils;
     
    type
         svm_node = record
              index : longint;
              value : double;
           end;
     
     
     type
        ADouble = array of double; // array of double
        PA_Double = ^ADouble; // pointer of an array of double
        Asvm_node = array of svm_node;
        PAsvm_node = ^Asvm_node;
     type
          svm_parameter = record
                svm_type : longint;
                kernel_type : longint;
                degree : longint;
                gamma : double;
                coef0 : double;
                cache_size : double;
                eps : double;
                C : double;
                nr_weight :
                 longint;
                weight_label : ^longint;
                weight : ^double;
                nu : double;
                p : double;
                shrinking : longint;
                probability : longint;
             end;   
    Type
        Pchar  = ^char;
        Plongint  = ^longint;
     
     
        Psvm_node  = ^svm_node;
        type  svm_problem = record
              l : longint;
              y : PA_Double;
              x : PAsvm_node;
           end;
        Psvm_parameter  = ^svm_parameter;
        Psvm_problem  = ^svm_problem;
     type
         svm_model = record
              param : svm_parameter ;    // parameter
              nr_class : longint ;        // number of classes, = 2 in regression/one class svm
              l : integer;            // total #SV
              SV : ^Psvm_node;         // SVs (SV[l])
              sv_coef : ^Pdouble ;    // coefficients for SVs in decision functions (sv_coef[n-1][l])
              rho : Pdouble;        // constants in decision functions (rho[n*(n-1)/2])
              probA:Pdouble;          // pariwise probability information
              probB : Pdouble;
     
              // for classification only
     
              label1 : integer;        // label of each class (label[n])
              nSV: ^longint;        // number of SVs for each class (nSV[n])
              // XXX
              free_sv : longint;        // 1 if svm_model is created by svm_load_model
          end;
    type
      Psvm_model = ^svm_model;
     
    {$IFDEF FPC}
    {$PACKRECORDS C}
    {$ENDIF}
     
    {$ifndef _LIBSVM_H}
    {$define _LIBSVM_H}
    { C++ extern C conditionnal removed }
     
    const
    DLLName = 'myDLL.DLL';
    C_SVC =0;
    NU_SVC =1;
    ONE_CLASS = 2;
    EPSILON_SVR=3;
    NU_SVR=4;
     
    const
     
    LINEAR=0;
    POLY =1;
    RBF=2;
    SIGMOID = 3;
    PRECOMPUTED=4;
     
     
     
    function _svm_train(prob : Psvm_problem; param:Psvm_parameter):Psvm_model;cdecl;external DLLName;
    function _PrintHelloyou():PCHAR; cdecl;external DLLName;
    { C++ end of extern C conditionnal removed }
    {$endif}
        { _LIBSVM_H  }
     
    implementation
    end.
    Form PAS:
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    unit Test_frame;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,SVM,SDF_SMF_ToSVM;
     
     
    type
      TForm4 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        OpenDialog1: TOpenDialog;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form4: TForm4;
      SDF_SMF_ToSVM :TSVMLaunch;
      my_property_Table : Pdouble;
    implementation
     
    {$R *.dfm}
     
     
    procedure TForm4.Button2Click(Sender: TObject);
    var
      Handle : Thandle;
      FileExt: string[5];
      my_Smffile: string;
      pointeur_tmp,pointeur_tmp2 : pointer;
      string1 :Pchar;
    begin
      SDF_SMF_ToSVM := TSVMLaunch.create;
      Opendialog2.Title := 'Open *.SMF file';
      Opendialog2.DefaultExt := '.SMF';
      Opendialog2.Filter := 'SMF File (*.SMF)|*.SMF';
      if Opendialog2.Execute then
      begin
        FileExt := AnsiUpperCase(ExtractFileExt(Opendialog2.FileName));
        if FileExt = '.SMF' then
        begin
          if FileExists(Opendialog2.FileName) then
          begin
            my_Smffile := Opendialog2.FileName;
            Edit2.Text := ExtractFileName(my_Smffile);
          end
          else
          begin
            MessageDlg('Select an existing SMF file.', mtInformation,
              [mbOk],
              0);
            Exit;
          end;
        end;
     
      end;
      Handle := LoadLibrary('DLL_libsvm3.dll');
       // _PrintHello();
        if Handle <> 0 then
        begin
     
        pointeur_tmp := GetProcAddress(Handle, '_PrintHelloyou');
        if pointeur_tmp <> nil then
             begin
           showmessage('debut de PrintHello');
           string1 := PrintHelloyou;
           showmessage('fin de PrintHello :'+ PAnsiChar(string1));
           end;
        pointeur_tmp2 := GetProcAddress(Handle, '_svm_train');
        if pointeur_tmp2 <> nil then
           begin
           showmessage('debut de svm_train');
           SDF_SMF_ToSVM.Remplissage_svm_problem(my_Smffile); // 
           my_model := _svm_train(SDF_SMF_ToSVM.my_svm_problem, SDF_SMF_ToSVM.UParameter);
           end;
        end;
        FreeLibrary(Handle);
     
     
     SDF_SMF_ToSVM.Free;
    end;
    end.
    fichier *.h

    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
    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
    48
    49
    50
    51
    52
    53
    54
    #ifndef _SVM_H
    #define _SVM_H
    #include <iostream>
    #include <string>
    #define EXPORTCALL __declspec(dllexport)
    using namespace std;
    #ifdef __cplusplus
    extern "C"  {
    #endif
     
    struct svm_node
    {
        int index;
        double value;
    };
     
    struct svm_problem
    {
        int l;
        double *y;
        struct svm_node **x;
    };
     
    enum { C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR };    /* svm_type */
    enum { LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED }; /* kernel_type */
     
    struct svm_parameter
    {
        int svm_type;
        int kernel_type;
        int degree;    /* for poly */
        double gamma;    /* for poly/rbf/sigmoid */
        double coef0;    /* for poly/sigmoid */
     
        /* these are for training only */
        double cache_size; /* in MB */
        double eps;    /* stopping criteria */
        double C;    /* for C_SVC, EPSILON_SVR and NU_SVR */
        int nr_weight;        /* for C_SVC */
        int *weight_label;    /* for C_SVC */
        double* weight;        /* for C_SVC */
        double nu;    /* for NU_SVC, ONE_CLASS, and NU_SVR */
        double p;    /* for EPSILON_SVR */
        int shrinking;    /* use the shrinking heuristics */
        int probability; /* do probability estimates */
    };
     
    EXPORTCALL struct svm_model *svm_train(const struct svm_problem *prob,  struct svm_parameter *param);
    EXPORTCALL char *PrintHelloyou();
    #ifdef __cplusplus
    }
    #endif
     
    #endif /* _SVM_H */

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    a par que tu semble utiliser dans Form PAS la DLL: Handle := LoadLibrary('DLL_libsvm3.dll');
    et que tu semble compiler avec "myDLL.dll" dans le code C++?

    Et aussi une fois compilé, j'imagine que tu copie la nouvelle DLL dans le repertoire de ton application appelante car lorsque tu utilise LoadLibrary avec juste le nom de la DLL, et dans ce cas, il cherche la DLL dans cet ordre
    1- dans le repertoire de l'application
    2- dans le repertoire courrant
    3- dans le repertoire systeme de window

    donc t'as peut-être une veille version de ta dll qui traine dans le repertoire
    de ton application pendant que tu copie la nouvelle version dans le repertoire system de window et donc c'est toujours la vielle qui est loadé?

    Sinon, faudrait analyser la DLL avec un outil comme
    Dependency Walker pour voir la décoration des functions exportées.

    et là...j'ai plus d'idée là!
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Merci pour ta réponse
    je vais essayer Dependency Walker

    En fait la librairie MyDLL.dll est la même que DLL_libSVM3.dll

    La dll est dans le même repertoire que le projet Delphi.

Discussions similaires

  1. Réponses: 18
    Dernier message: 25/06/2007, 09h45
  2. comment utiliser les fonctions d'une dll
    Par sebled dans le forum MFC
    Réponses: 3
    Dernier message: 24/02/2006, 16h59
  3. Retrouver les valeurs des paramètres des fonctions d'une DLL
    Par Bernard Martineau dans le forum Langage
    Réponses: 6
    Dernier message: 08/11/2005, 10h42
  4. utilisation des fonctions d'une dll
    Par jackk dans le forum C++
    Réponses: 14
    Dernier message: 15/06/2005, 16h50

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