(MATLAB/C++) 是否可以将函数作为参数传递给 C++ MEX 函数?

(MATLAB/C++) Is it possible to pass functions as arguments to C++ MEX functions?

我只使用 mex 函数几个星期,现在正在编写 Runge-Kutta 四阶求解器作为 C++ mex 函数。 我想知道是否可以将函数作为输入。 实际上,如果我的动力学函数是用 MATLAB 编写的并将其直接传递到我的 RK4 mex 函数,那就太好了。 例如,如果动力学由 Duffing 方程控制,用 MATLAB 编写:

function xdot = Duffing(t,x)
xdot = [x(2); 0.3*cos(t)-0.22*x(2)+x(1)-x(1)^3];
end

(我意识到这也可以写成 Duffing = @(t,x) (随便什么))

有没有办法从 mex 函数中调用动态函数,或者 inputs[] 是否仅限于数字类型? 我尝试了以下方法:

class MexFunction : public matlab::mex::Function {
public:
    void operator()(ArgumentList outputs, ArgumentList inputs) {
        
//     Access the dynamics function
        typedef TypedArray<double> xdot_type (TypedArray<double>, TypedArray<double>);
        xdot_type xdot;
        xdot = inputs[0];
    

当然,这不起作用,因为 inputs[0] 不可分配给“TypedArray<double> (TypedArray<double>, TypedArray<double>)”,因为我认为 ArgumentList 认为 inputs[0] 应该是纯数字。 谁能想到解决这个问题的方法,还是我只需要用 C++ 编写我的动态函数? 期待一些建议! 托马斯

只需快速浏览一下 MATLAB C++ API 文档,您似乎可以使用此处找到的 matlab::engine::MATLABEngine::feval 界面来完成此操作:

https://www.mathworks.com/help/matlab/matlab_external/cpp-mex-api.html?searchHighlight=fevalAsync&s_tid=srchtitle#mw_723048ca-e22f-4bfb-aa12-47b8007da774

即,将您的函数名称作为字符串传递到 C++ mex 文件中,您可以通过 matlab::data::CharArray 语法从 ArgumentList 中获取该字符串:

void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
    matlab::data::CharArray fname = inputs[0];
    etc.

然后将 fname 转换成 std::u16string 并在 feval 界面中使用它。

除了@James 的回答之外,还可以在位于 C++ Mex 和您的 Matlab 函数之间的代码生成的薄包装层中使用 coder.extrinsic

              calls                                                     calls
C++ Mex layer ----> Code-Generated Matlab wrapper lib (coder.extrinsic) ----> Matlab function

但是,这可能不是一个好的设计。我假设您出于性能原因使用 C++。暂停程序的执行,将数据从 C++ 编组到 Matlab 是很慢的。如果您是 运行 时间步长模拟,您可能会发现互操作代码成为性能瓶颈。更好的设计可能是调整您的 动力学方程 Matlab 代码,使其成为 code-generatable,然后您可以直接从生成的 C 代码调用 C++。