通过 C/C++回调到 matlab 引擎

发布于 2024-12-29 20:51:43 字数 1072 浏览 4 评论 0 原文

我有一个 C++ 文件:

  • 启动 matlab 引擎
  • 调用 matlab_optimize() (一个编译后的 m 文件,在内部运行 matlab 优化器之一)
  • 打印结果
  • 停止引擎并退出

这工作正常。我现在想将第二行更改为

  • 调用 matlab_optimize(obj_fun)

其中 obj_fun() 是我的 C++ 代码中定义的函数,它本身将回调到其他代码中。本质上,我希望在 matlab_optimize 内部使用的 matlab 优化器使用我提供的函数指针作为目标函数。

我不能将 obj_fun() 编译为独立的 mex 文件,因为我希望它与启动 matlab 引擎(驱动整个过程)的 c++ 进程进行通信。

2009 年的新闻组帖子 似乎表明这是不可能的。然后再次使用 Matlab C++ 数学库工具箱 似乎确实能够做到这一点

谷歌搜索还 揭示了这个生成的片段

/*
 * Register a function pointer as a MATLAB-callable function.
 */
extern void mexRegisterFunction(void);

这似乎正是我想要的,但是文件是 2000 年的,我在 matlab 文档中没有找到任何对此函数的引用。那么如何使用这个呢?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

赴月观长安 2025-01-05 20:51:43

您可以使用 mclmcrrt.h 标头中的 mclCreateSimpleFunctionHandle 函数来实现此功能。

它将带有原型 void(*) (int, mxArray*, int, mxArray) 的函数转换为 mxArray 结构。

您可以将其传递给 MATLAB 侧函数并像一般 MATLAB 函数一样调用它,而无需使用 mex 文件进行任何操作。

在 C/C++ 方面:

void callback(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
   <some manipulations with data>;
}

...
//calling the matlab function
matlab_function(mclCreateSimpleFunctionHandle(callback));

在 MATLAB 方面:

function [] = matlab_function(function)
    function(<any variable>)
end

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
花伊自在美 2025-01-05 20:51:43

我就这个问题联系了 Mathworks,并设法让一切正常运行。这个问题是能够将 Python 函数的回调直接传递给 Matlab 的更广泛努力的一部分。

有关此博文的完整详细信息github 上提供的代码

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.

贵在坚持 2025-01-05 20:51:43

我要感谢 totoro 的有用评论,这里有一些 C++ 方面更详细的实现示例:

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
}

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
}
女中豪杰 2025-01-05 20:51:43

如果有办法做到这一点,我还从未见过。更糟糕的是,您引用的 Matlab C++ 数学库不再存在:

http://www .mathworks.com/matlabcentral/newsreader/view_thread/267802

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

指尖上得阳光 2025-01-05 20:51:43

似乎您可以从任何 MATLAB 函数创建可 C 连接的库
(参见此处)。如果这像宣传的那样有效,我认为你应该能够以不同的方式做你想做的事。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文