Calling C functions using MATLAB.

4 visualizaciones (últimos 30 días)
Estel Ferrer Torres
Estel Ferrer Torres el 29 de En. de 2020
Editada: Estel Ferrer Torres el 31 de En. de 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.

Respuestas (2)

James Tursa
James Tursa el 29 de En. de 2020
Editada: James Tursa el 29 de En. de 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 comentario
Estel Ferrer Torres
Estel Ferrer Torres el 30 de En. de 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...

Iniciar sesión para comentar.


Estel Ferrer Torres
Estel Ferrer Torres el 30 de En. de 2020
Editada: Estel Ferrer Torres el 30 de En. de 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 comentarios
James Tursa
James Tursa el 31 de En. de 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 el 31 de En. de 2020
Editada: Estel Ferrer Torres el 31 de En. de 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.

Iniciar sesión para comentar.

Categorías

Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by