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:
J'arrive à récupérer directement la chaîne de caractères dans delphi. C'était assez fastidieux quand même ^^.
Code : Sélectionner tout - Visualiser dans une fenêtre à part char * PrintHelloyou();
Maintenant je dois utiliser une autre fonction de la dll, qui renvoie un pointeur sur une structure
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 struct svm_model *svm_train(const struct svm_problem *prob, struct svm_parameter *param);
Ici:
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);
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 ::
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
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.
fichier *.h
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.
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 */
Partager