将matlab函数集成到c#项目中

Posted

技术标签:

【中文标题】将matlab函数集成到c#项目中【英文标题】:Integrating matlab functions into c# project 【发布时间】:2014-01-22 12:23:51 【问题描述】:

我有一个很好的核心 matlab 函数的 .net 程序集,当然是用 matlab 编译器创建的。对于接受数字或数字数组的函数,这很好;我可以在 c# 中编写代码,而不必恢复到 matlab(嗯,必须安装 RCM;这很好)。

但是,对于必须引用其他函数的函数,到目前为止,我能找到的唯一让 c# 程序运行的方法是将这两个函数编译到程序集中。为了更好地解释,假设我有一个库,其中存储了 ode45 例程。如果我想解一个特定的方程,比如说像dy/dx = -y这样简单的东西,那么我必须创建一个matlab脚本文件,它可以写成如下:

function dydx = diffeq(x, y)
dydx = -y

[显然解析解存在,但为了这个例子,假设我想这样解决]

现在为了解决这个等式,我必须将此函数作为方法添加到我的类中以编译到 .net 程序集中。这当然会破坏我图书馆的一般性。我希望在与我的核心数学函数库不同的库中使用特定于应用程序的方程。也就是说,ODE45 方法应该驻留在比“diffeq”方法所在的库中“更核心”的库中。

除此之外,我更喜欢在我可以直接编辑的 c# 类中创建“diffeq”方法,例如VS2012。我想直接编辑方程,而不是每次都进入matlab重新编译一个程序集。

为了解决这个问题,我已经对包含 ode45 代码和我的微分方程方法的程序集进行了反编译;事实证明,该组件只不过是 MCR 的一个接口;程序集中的 diffeq 方法返回如下内容:

return mcr.EvaluateFunction(numArgsOut, “diffeq”, new object[0]);

我们注意到函数/方法“diffeq”不是 MCR 的一部分; MCR 不变。但是,我在程序集中的任何地方都找不到方程式。

这引出了“老兄,我的功能在哪里?”的问题

在程序集中有一个“资源”组件,我们可以在其中找到 [classname].ctf,并在其中找到一些机器代码。这看起来是加密的,但方程式可能隐藏在那里。如果是这样,那将是我在尝试时故意阻止的尝试,感谢 MathWorks 让我无法避免进入 matlab 应用程序!

但是,许可中似乎没有任何东西可以阻止我想做的事情;我认为如果 mathworks 允许像这样开放的方法会很棒,但在此期间,有人知道如何做到这一点吗?

【问题讨论】:

【参考方案1】:

“MATLAB 编译器”的名称有些误导。它更像是一个部署解决方案,而不是一个真正意义上的编译器(见下面的注释)。它主要用于将 MATLAB 应用程序分发给最终用户,而不需要他们完全安装 MATLAB(只需要安装免版税的MCR runtime)。

MCR 实际上是 MATLAB 引擎的精简版以及随附的库。

当您使用 MATLAB Compiler 生成二进制包时,结果是调用 MCR 运行时的特定于目标的包装器(无论是独立应用程序、C/C++ 共享库、Java 包还是 .NET 程序集)。生成的二进制文件包括一个嵌入式 CTF 存档,其中包含所有原始 MATLAB 内容(您的 M 文件和其他依赖项),但采用加密形式。首次执行时,CTF 存档被提取到一个临时文件夹,然后 MCR 像典型的 MATLAB 代码一样在运行时解释 M 文件(仍然加密)。

deploytool (mcc -C) 中有一个选项告诉编译器不要将 CTF 存档作为资源嵌入到二进制文件中,而是将其作为单独的文件放置在生成的二进制文件旁边(此 CTF 存档可以作为普通的 ZIP 文件进行检查,但里面的源文件当然仍然是加密的)。

有关详细信息,请参阅以下文档页面:

Application Deployment Products and the Compiler Apps


PS:事实上,MATLAB Compiler 最初是作为一个产品将 MATLAB 代码转换为完整的 C/C++ 代码,它使用现已停产的“MATLAB C/C++ 数学库”(没有运行时要求,您只需编译生成的 C++ 代码并链接到某些共享库;结果是真正编译的可执行文件,而不是包装器)。这个功能在 MATLAB 7 发布时完全changed (原因是旧方法只支持 MATLAB 语言的一个子集,而使用当前的 MCR 机制可以部署几乎任何代码)。多年后,MATLAB 添加了一个新产品来取代曾经被删除的代码翻译功能,即MATLAB Coder。

【讨论】:

所以你的意思是,在程序运行时,可以在 temp 文件夹中访问普通的 MATLAB 代码? 对不起,我的措辞有点模棱两可;提取的文件保持加密形式(AES 加密)。我想 MCR 知道秘密对称密钥,因此能够像往常一样解密然后执行代码。有趣的是,只有 M 文件被加密(该 CTF 存档中包含来自您的prefdir 的其他资源文件和首选项未加密)。目录结构复制了相同的文件名,但M文件中的内容基本上是乱码。

以上是关于将matlab函数集成到c#项目中的主要内容,如果未能解决你的问题,请参考以下文章

在c#中调用带参数的matlab函数

C#编写的DLL文件怎么导出函数?

从 C# 调用函数时的 Matlab 异常(MWMCR::EvaluateFunction 错误)

安装或集成 MCR Matlab 的 .Net 托管

从 C# 应用程序内部调用 Matlab 编译器会引发异常

MATLAB .NET 程序集(未定义函数或变量“前馈网络”)