Calling C functions using MATLAB.

4 Ansichten (letzte 30 Tage)
Estel Ferrer Torres
Estel Ferrer Torres am 29 Jan. 2020
I have a simple c function stored in clibs.c. The C file looks like the following:
/////clibs.c
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <mex.h>
#include "shrhelp.h"
#include "clibs.h"
EXPORTED_FUNCTION void twoBP(double *xdot, double *x){
xdot[0] = x[3];
xdot[1] = x[4];
xdot[2] = x[5];
xdot[3] = x[0];
xdot[4] = x[1];
xdot[5] = x[2];
return;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray*prhs[] )
{
}
////end clibs.c
I also have the associated header file (clibs.h):
////clibs.h
#ifndef clibs_h
#define clibs_h
#include "shrhelp.h"
/* Function declarations */
EXPORTED_FUNCTION void twoBP(double *, double *);
#endif
///end clibs.h
In order to call twoBP function form MATLAB I simply used the follwing statemes:
mex clibs.c
loadlibrary('clibs')
xdot = zeros(1,6);
x = [1,2,3,4,5,6];
xdot = calllib('clibs','twoBP',xdot,x);
The enviroment is working and it returns xdot = [4,5,6,1,2,3] as expected.
Furthermore I can verify that the library had been well loaded by typing in the command window...
>>libfunctions('clibs')
which returns...
Functions in library clibs:
twoBP
My problem appears when I try to compile a slightly different C function:
EXPORTED_FUNCTION void twoBP(double *xdot, double *x,void (*camp)(double x, double *y, int n, double *f)){
xdot[0] = x[3];
xdot[1] = x[4];
xdot[2] = x[5];
xdot[3] = x[0];
xdot[4] = x[1];
xdot[5] = x[2];
return;
}
As you can see this new twoBP function takes an extra input argument: a function defined as void (*camp)(double x, double *y, int n, double *f).
I modify clibs.h accordingly:
#ifndef clibs_h
#define clibs_h
#include "shrhelp.h"
/* Function declarations */
EXPORTED_FUNCTION void twoBP(double *, double *,void (*)(double, double *, int, double *));
#endif
However, when I try to execute the matlab code...
mex clibs.c
loadlibrary('clibs')
libfunctions('clibs')
It returns:
No methods for class lib.clibs.
I do not know how to fix this problem. Any idea?
Thank you for your attention.
Estel.

Antworten (2)

James Tursa
James Tursa am 29 Jan. 2020
Bearbeitet: James Tursa am 29 Jan. 2020
This:
void (*camp)(double x, double *y, int n, double *f)
is not a function as you claim. It is a pointer to a function that has the specified signature (takes four inputs and doesn't return anything). So this expression that you have in the prototype
void (double, double *, int, double *)
is incorrect. I am guessing this is what you fed to MATLAB. Had you fed it into a compiler I think you would have gotten an error. The proper expression is the first one. Simply use that in your h file. Or if you don't like the variable names (they are optional and don't hurt anything), then just
void (*)(double, double *, int, double *)
Your prototype in the h file would be (if I remove that extra double which doesn't appear in the actual function signature):
EXPORTED_FUNCTION void twoBP(double *, double *,void (*)(double, double *, int, double *));
  1 Kommentar
Estel Ferrer Torres
Estel Ferrer Torres am 30 Jan. 2020
Thank you for your replay. You are right. I change the header for EXPORTED_FUNCTION void twoBP(double *, double *,void (*)(double, double *, int, double *)); but I am still having exactly the same problem...

Melden Sie sich an, um zu kommentieren.


Estel Ferrer Torres
Estel Ferrer Torres am 30 Jan. 2020
Bearbeitet: Estel Ferrer Torres am 30 Jan. 2020
I tried to simplify my problem:
I define the ponter function *camp with only one input double *.
EXPORTED_FUNCTION void twoBP(double *xdot, double *x,void (*camp)(double x)){
xdot[0] = x[3];
xdot[1] = x[4];
xdot[2] = x[5];
xdot[3] = x[0];
xdot[4] = x[1];
xdot[5] = x[2];
return;
}
So the header file looks like this:
EXPORTED_FUNCTION void twoBP(double *, double *,void (*)(double));
With this simplification MATLAB detects the function twoBP and returns:
Functions in library clibs:
twoBP
However, when I define the pointer function with two inputs, MATLAB does not detect twoBP in the library and returns:
No methods for class lib.clibs.
I dont understand.
  4 Kommentare
James Tursa
James Tursa am 31 Jan. 2020
I don't know how to advise based on what I know so far. How can Python pass a C function pointer to a C library?
Estel Ferrer Torres
Estel Ferrer Torres am 31 Jan. 2020
Bearbeitet: Estel Ferrer Torres am 31 Jan. 2020
Don't know exactly because I don't have the hole code, but something like this:
def rk78 (t, y, n, h, hmin, hmax, tol, vfield):
# Convert parameter to ctype friendly
tc = c_double(t)
yc = (c_double * n)(*y)
nc = c_int(n)
hc = c_double(h)
hminc = c_double(hmin)
hmaxc = c_double(hmax)
tolc = c_double(tol)
# Call C-written RK78 integrator
clib.rk78nw(byref(tc), byref(yc), nc, byref(hc), hminc, hmaxc, tolc, vfield)
# Modify Python parameters
t = tc.value
h = hc.value
for i in range(n): y[i] = yc[i]
return t, h, y
where vfield is the pointer function. I think that you can initialize vfield like:
vfield = clib.functionName('input1', 'input2',...)
I think it does not return the outputs but a pointer to functionName.
But I'm not sure about this. I will ask to the person that write the code.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Write C Functions Callable from MATLAB (MEX Files) finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by