Calling C functions using MATLAB.

9 views (last 30 days)
Estel Ferrer Torres
Estel Ferrer Torres on 29 Jan 2020
Edited: Estel Ferrer Torres on 31 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.

Answers (2)

James Tursa
James Tursa on 29 Jan 2020
Edited: James Tursa on 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 Comment
Estel Ferrer Torres
Estel Ferrer Torres on 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...

Sign in to comment.


Estel Ferrer Torres
Estel Ferrer Torres on 30 Jan 2020
Edited: Estel Ferrer Torres on 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 Comments
James Tursa
James Tursa on 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 on 31 Jan 2020
Edited: Estel Ferrer Torres on 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.

Sign in to comment.

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!