【问题标题】:Passing C/C++ callbacks into the matlab engine将 C/C++ 回调传递到 matlab 引擎
【发布时间】:2012-01-30 18:09:14
【问题描述】:

我有一个 C++ 文件:

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

这很好用。我现在想把第二行改成

  • 致电matlab_optimize(obj_fun)

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

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

A newsgroup post from 2009 似乎表明这是不可能的。然后是 Matlab C++ 数学库工具箱does seem to be able to do this

也搜索一下reveals this generated snippet:

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

这似乎正是我想要的,但该文件来自 2000 年,我在任何地方的 matlab 文档中都没有找到对这个函数的引用。那么这个怎么用呢?

【问题讨论】:

  • 只是一个建议,你认为你可以接受他们通过套接字通信吗?
  • 我可以让事情通过套接字工作,但此时它并不值得付出努力,所以我会放弃这条路线。

标签: c++ matlab mex matlab-deployment matlab-engine


【解决方案1】:

您可以使用 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

【讨论】:

    【解决方案2】:

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

    this blog postcode available on github 的详细信息。

    【讨论】:

    • 我不清楚的是:您在这里使用的是 MEX 界面还是 Engine 界面(它们不同)? Engine 接口可让您从 Python 调用 MATLAB。您需要这样做,还是只需要从 MATLAB 中调用 Python?我有一个类似的问题,我需要双向通信:我需要从语言 X 中调用 MATLAB(评估 MATLAB 代码),但我需要 MATLAB 能够在这种评估期间回调语言 X。
    • 我使用了 mex 界面。对我来说,让双向通信正常工作的诀窍是你可以简单地将函数句柄(指针)作为整数传递。
    • 我也终于让它工作了,使用编码为uint64的指针。我使用了一个指向具有多个虚函数的 C++ 对象的指针。该对象是在管理通信通道的第一个 MEX 文件中创建的,其他 MEX 文件通过此指针访问它并将其称为虚拟函数。感谢您的提示!
    【解决方案3】:

    我要感谢 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
    }
    

    【讨论】:

    • 您认为您可以在这里提供一个完整的工作示例吗?我不确定我应该如何编译和运行这个示例。
    • 我们能否获得一个完整的最小工作示例以及如何编译和运行该示例?谢谢@totoro
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      您似乎可以从任何 MATLAB 函数创建一个 c 链接库 (see here)。如果这如宣传的那样有效,我认为你应该能够以不同的方式做你想做的事。

      【讨论】:

      • 这是我对 matlab_optimize() 所做的,将其编译为一个共享库,然后我可以与其他本地代码进行交互。问题是如何将函数句柄传递给它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 2012-06-08
      • 2020-08-03
      • 1970-01-01
      相关资源
      最近更新 更多