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 */