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:
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:
struct svm_model *svm_train(const struct svm_problem *prob, struct svm_parameter *param);
et c'est là que ca coince :cry:. 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:
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:
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:
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:
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 */ |