Passing C/C++ callbacks into the matlab engine

2019-05-10 09:03发布

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?

5条回答
孤傲高冷的网名
2楼-- · 2019-05-10 09:21

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.

查看更多
Melony?
3楼-- · 2019-05-10 09:27

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
查看更多
Ridiculous、
4楼-- · 2019-05-10 09:28

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
}
查看更多
等我变得足够好
5楼-- · 2019-05-10 09:30

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.

查看更多
爷、活的狠高调
6楼-- · 2019-05-10 09:35

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

查看更多
登录 后发表回答