How to pass a Matlab function handle to C-Mex Code

15 Ansichten (letzte 30 Tage)
Friedrich
Friedrich am 18 Okt. 2024
Kommentiert: Friedrich am 22 Okt. 2024 um 12:59
Hi all,
I am new to C-Mex and maybe my task is too ambitious for now. I am trying to write some ODE-Solvers with C-Mex functions so that the solvers are callable from Matlab. To achieve this I need to pass the model equations from Matlab as function handles to the C-Code. I am struggeling here since the model equations return an array. I simply don't know how to implement such thing with C-Mex.
Could anyone provide a simple example so I could get a better understanding?
Thanks a lot.

Akzeptierte Antwort

James Tursa
James Tursa am 21 Okt. 2024
Bearbeitet: James Tursa am 22 Okt. 2024
To use a function handle in a mex function with C array as an input to the function handle, you can use mexCallMATLAB( ) with the function handle as an argument to the feval( ) function along with converting the C array to an mxArray inside the C code. E.g., compile this C code (CAUTION: Bare Bones for Example Only ... No Argument Checking Included):
// fnhandle.c , evaluates function handle inside mex function.
// This example assumes function handle takes one input
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxArray *rhs[2]; // mxArrays used for input to mexCallMATLAB
double data[3] = {1.0, 2.0, -3.0}; // Some sample data in a C array
double *pr; // Pointer used for copying C array to mxArray
// Copy function handle to input array
rhs[0] = (mxArray *) prhs[0];
// Create input to the function handle
rhs[1] = mxCreateDoubleMatrix(1,3,mxREAL);
// Copy the C array data to the mxArray
pr = (double *) mxGetData(rhs[1]);
pr[0] = data[0]; pr[1] = data[1]; pr[2] = data[2];
// Call feval( ) to evaluate the function handle with one input and put the result in plhs[0]
mexCallMATLAB(1,plhs,2,rhs,"feval");
// Destroy the temporary mxArray
mxDestroyArray(rhs[1]);
}
And run it as follows:
>> mex fnhandle.c
Building with 'MinGW64 Compiler (C)'.
MEX completed successfully.
>> fh = @(x)2*x+1
fh =
function_handle with value:
@(x)2*x+1
>> fnhandle(fh)
ans =
3 5 -5
>> fh = @(x)x.^2-2
fh =
function_handle with value:
@(x)x.^2-2
>> fnhandle(fh)
ans =
-1 2 7
Note that MATLAB workspace variables used in the function handle are embedded in the function handle at the time of function handle creation, so they get automatically passed into the mex routine as part of the function handle. E.g.,
>> A = [2;-1;2];
>> fh = @(x)x*A % A is part of the function handle fh
fh =
function_handle with value:
@(x)x*A
>> fnhandle(fh) % This will do an inner product
ans =
-6
>> fh = @(x)A*x % A is part of the function handle fh
fh =
function_handle with value:
@(x)A*x
>> fnhandle(fh) % This will do an outer product
ans =
2 4 -6
-1 -2 3
2 4 -6
In these last examples, the A variable from the MATLAB workspace is embedded in the function handle fh, so it gets passed into the mex routine as part of fh.
If you need to use the results of the function handle call inside the C mex function, then instead of putting the result in plhs[0] you could put the result in a different mxArray and then use a pointer to get at the data of this mxArray. E.g., in the above code you could have done this:
pr = (double *) mxGetData(plhs[0]);
Or using a different output variable the above code could be changed to:
mxArray *lhs[1];
:
mexCallMATLAB(1,lhs,2,rhs,"feval");
pr = (double *) mxGetData(lhs[0]);
// Use pr here
mxDestroyArray(lhs[0]);
And then dereferenced pr to get at the results of the function handle call inside the C code.

Weitere Antworten (1)

Bruno Luong
Bruno Luong am 18 Okt. 2024
Rather than using function handle, call MATLAB with function name using mexCallMATLAB

Kategorien

Mehr zu Mathematics and Optimization finden Sie in Help Center und File Exchange

Tags

Produkte


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by