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

15 visualizzazioni (ultimi 30 giorni)
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.

Risposta accettata

James Tursa
James Tursa il 21 Ott 2024
Modificato: James Tursa il 22 Ott 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.

Più risposte (1)

Bruno Luong
Bruno Luong il 18 Ott 2024
Rather than using function handle, call MATLAB with function name using mexCallMATLAB

Categorie

Scopri di più su Mathematics and Optimization in Help Center e File Exchange

Tag

Prodotti


Release

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by