问题
I have a C++ file that:
- starts the matlab engine
- calls
matlab_optimize()
(a compiled m file that runs one of matlab optimizers internally) - prints the result
- stops the engine and quits
This works fine. I now want to change the second line into
- calls
matlab_optimize(obj_fun)
Where obj_fun()
is a function defined in my C++ code which itself will callback into other code. Essentially I want the matlab optimizer used internally in matlab_optimize
to use my supplied function pointer as the objective function.
I cant just compile obj_fun()
as a standalone mex file since I want it to communicate with the c++ process that starts the matlab engine (which drives the whole thing).
A newsgroup post from 2009 seems to indicate this is not possible. Then again the Matlab C++ Math Library Toolbox does seem to be able to do this.
Googling around also reveals this generated snippet:
/*
* Register a function pointer as a MATLAB-callable function.
*/
extern void mexRegisterFunction(void);
Which seems exactly what I want but the file is from 2000, and I find no reference to this function in the matlab docs anywhere. So how to use this?
回答1:
You can use mclCreateSimpleFunctionHandle function from the mclmcrrt.h header to make this feature.
It сonverts a function with a prototype void(*) (int, mxArray*, int, mxArray) to the mxArray structure.
You can pass it to the MATLAB side function and call it like general MATLAB functions without any manipulations with mex files.
On the C/C++ side:
void callback(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
<some manipulations with data>;
}
...
//calling the matlab function
matlab_function(mclCreateSimpleFunctionHandle(callback));
On the MATLAB side:
function [] = matlab_function(function)
function(<any variable>)
end
回答2:
I contacted Mathworks about the issue and managed to get it all working. This question was part of a wider effort of being able to pass callbacks to Python functions directly to Matlab.
Full details on this blog post and code available on github.
回答3:
I'd like to thank totoro for his helpful comment, here some more detailed implementation example on C++ side:
void fromMatlabCallback(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
cout << "WOW I'm from Matlab. and it passes me a param: ";
int aa = mxGetScalar(prhs[0]); // it is first param; nrhs tells how many there are
cout << aa << "\n";
}
void InitializingFunc()
{
mxArray *func_ptr = mclCreateSimpleFunctionHandle(fromMatlabCallback);
mxArray *retVal_ptr = NULL;
mlfUntitled(1, &retVal_ptr , func_ptr); //Untitled is name of my main Matlab func
}
回答4:
If there is a way to do that, I've never seen it. To make matters worse, the Matlab C++ Math Library you reference no longer exists:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/267802
回答5:
It seems that you can create a c-linkable library from any MATLAB function (see here). If this works as advertised, I think you should be able to do what you want though in a different way.
来源:https://stackoverflow.com/questions/9068558/passing-c-c-callbacks-into-the-matlab-engine