Posted By: Niels
Problem with passing struct elements to a dll function - 02/06/17 08:07
Hi,
This is my first post, so hello to everybody, happy to start sharing ideas with all of you.
I am trying to use a separate dll library to perform regression with Support Vector Machine in Zorro. The library is libsvm.dll and contains several functions. It is a C++ library with a C-API (compiled with EXTERN C).
I declare and initialise the required dll functions prototypes in my header, for example :
I am able to call the dll functions in the run (or main) script, however the functions seems not to recognise some struct components (variables) passed through the function argument as a pointer, and so doesn’t work properly.My header SVM.h with the structs :
My main function :
For example when I initialise param.C and call svm_check_parameter(&prob, ¶m) the functions returns me an error : C<=0 , however when I check param.C with “watch” it gives me 1.0.
Strangely, I also hade the same problem with param.cache_size whose value was not recognised by the same dll function. But I resolve it by changing it to a float, whereas a double is expected in the original dll function.
I also tried to declare my struct as global, but this doesn’t change anything.
Does anyone have any idea how to make this work?
Thank you for your help or comments.
Niels
This is my first post, so hello to everybody, happy to start sharing ideas with all of you.
I am trying to use a separate dll library to perform regression with Support Vector Machine in Zorro. The library is libsvm.dll and contains several functions. It is a C++ library with a C-API (compiled with EXTERN C).
I declare and initialise the required dll functions prototypes in my header, for example :
Code:
const char* __cdecl svm_check_parameter(const svm_problem *prob, const svm_parameter *param); #define PRAGMA_API svm_check_parameter;libsvm!svm_check_parameter
I am able to call the dll functions in the run (or main) script, however the functions seems not to recognise some struct components (variables) passed through the function argument as a pointer, and so doesn’t work properly.My header SVM.h with the structs :
Code:
#ifndef SVM_h #define SVM_h //--------------------------------------------------------------------------------------------------- // Some definitions //Svm_type #define C_SVC 0 #define NU_SV 1 #define ONE_CLASS 2 #define EPSILON_SVR 3 #define NU_SVR 4 //Kernel_type #define LINEAR 0 #define POLY 1 #define RBF 2 #define SIGMOID 3 #define PRECOMPUTED 4 //--------------------------------------------------------------------------------------------------- //Struct definitions typedef struct { int index; double value; } svm_node; typedef struct { int l; double *y; svm_node **x; } svm_problem; typedef struct { 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 float 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 } svm_parameter; // svm_model typedef struct { svm_parameter param; // parameter int nr_class; // number of classes, = 2 in regression/one class svm int l; // total #SV svm_node **SV; // SVs (SV[l]) double **sv_coef; // coefficients for SVs in decision functions (sv_coef[k-1][l]) double *rho; // constants in decision functions (rho[k*(k-1)/2]) double *probA; // pariwise probability information double *probB; int *sv_indices; // sv_indices[0,...,nSV-1] are values in [1,...,num_traning_data] to indicate SVs in the training set */ // for classification only int *label; // label of each class (label[k]) int *nSV; // number of SVs for each class (nSV[k]) // nSV[0] + nSV[1] + ... + nSV[k-1] = l // XXX int free_sv; // 1 if svm_model is created by svm_load_model // 0 if svm_model is created by svm_train } svm_model; //--------------------------------------------------------------------------------------------------- // Train and predict functions svm_model* __cdecl svm_train(const svm_problem *prob, const svm_parameter *param); //return a pointer to a SVM model #define PRAGMA_API svm_train;libsvm!svm_train double __cdecl svm_predict(const svm_model *model, const svm_node *x); #define PRAGMA_API svm_predict;libsvm!svm_predict //Check function const char* __cdecl svm_check_parameter(const svm_problem *prob, const svm_parameter *param); #define PRAGMA_API svm_check_parameter;libsvm!svm_check_parameter #endif
My main function :
Code:
//---------------------------------------------------------------------------------+ // Preprocessors + //---------------------------------------------------------------------------------+ #include <default.c> #include <SVM.h> //---------------------------------------------------------------------------------+ //Run + //---------------------------------------------------------------------------------+ function main() { // SVM variables----------------------------------------------+ int i,m,j; double norm_x; svm_parameter param;/ svm_problem prob; svm_node* x_space; //Fill in a parameter structure param.svm_type = EPSILON_SVR; param.kernel_type = LINEAR; param.degree = 1; // for poly param.gamma = 0.5; //default 1/number of features param.coef0 = 0; // for poly/sigmoid param.cache_size = 100.0; // in MB defaut 100 param.eps = 0.001; //default 0.001 param.C= 1.0; //default 1 param.nr_weight = 0; // for C_SVC param.weight_label = NULL; // for C_SVC param.weight = NULL; // for C_SVC param.nu = 0.5; // for NU_SVC, ONE_CLASS, and NU_SVR param.p = 0.1; //the epsilon for SVR default 0.1 param.shrinking = 0; // use the shrinking heuristics param.probability = 0; // do probability estimates //Problem structure definition and filling prob.l = 11; // number of training data // INPUT and DATA preparation--------------------------------------------------------------------------------------+ //Input target int feat = 1; int elements = prob.l * (feat+1); prob.y = malloc(sizeof(double)*prob.l); prob.x = malloc(sizeof(svm_node*)*prob.l); x_space = malloc(sizeof(svm_node)*elements); j=0; for(i=0; i<prob.l; i++){ // lines (prob.x)[i] = &x_space[j]; x_space[j].index = 1; // only one indice norm_x = (double)i/(prob.l-1.0); x_space[j].value = norm_x; //next col j ++j; // here same as j++ x_space[j].index = -1; ++j; } (prob.y)[0] = 1; (prob.y)[1] = 6; (prob.y)[2] = 4; (prob.y)[3] = 8; (prob.y)[4] = 15; (prob.y)[5] = 12; (prob.y)[6] = 18; (prob.y)[7] = 20; (prob.y)[8] = 19; (prob.y)[9] = 22; (prob.y)[10] = 25; //************Here param.C value is not correctly passed char* err; err = svm_check_parameter(&prob, ¶m); if(*err!=NULL) watch("Check: ", err); // returns me C<=0 by the external function watch("C: ", param.C); // returns me correctly 1.0 free(prob.y); free(x_space); free(prob.x); }
For example when I initialise param.C and call svm_check_parameter(&prob, ¶m) the functions returns me an error : C<=0 , however when I check param.C with “watch” it gives me 1.0.
Strangely, I also hade the same problem with param.cache_size whose value was not recognised by the same dll function. But I resolve it by changing it to a float, whereas a double is expected in the original dll function.
I also tried to declare my struct as global, but this doesn’t change anything.
Does anyone have any idea how to make this work?
Thank you for your help or comments.
Niels