我正在尝试从在Linux容器上运行的C#(.NET Core)调用使用MathWorks MATLAB编译器SDK创建的共享库。
我有一个matlab .m文件,已使用MATLAB R2018b编译器SDK将其编译为.dll。因为最终的执行环境是在Linux容器上运行的.NET Core 2.2,所以我选择了“C共享库”选项。我使用.NET的DLLImport机制将该共享库称为“共享库”。
这是我的项目中的一些代码。这段代码是KISS级别的,因为在开始主项目之前,我需要了解如何在Linux上集成MATLAB和C#。
haveSomePi.m
function hal = haveSomePi()
hal = 3.1415;
end
我的数学
extern LIB_MyMath_C_API bool MW_CALL_CONV mlfHaveSomePi(int nargout, mxArray** hal);
MyMathWrapper.cs
[DllImport("MyMath.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void mlfHaveSomePi(int nargout, ref IntPtr hal);
MyMathWrapperTests.cs
[TestMethod]
public void ShouldReturnPi()
{
var hal = IntPtr.Zero;
MyMathWrapper.mlfHaveSomePi(1, ref hal);
double result = (double)hal;
Assert.AreEqual(3.1415, result, 1e-5);
}
预期结果是测试方法中的断言通过。之所以失败,是因为在这种情况下尝试将IntPtr转换为 double 没有意义。我敢肯定,有一种方法可以取消引用IntPtr以获得潜在的双重 yield ,我只是还没有发现那种特别的信息。
将.m文件编译成.NET库和COM对象时,我已经成功了。我不认为我可以在Linux上使用这两个库中的任何一个,因为每个操作系统的二进制加载/链接格式存在差异。当在COM对象中调用该方法时,我能够将IntPtr直接转换为double,因此在后台一定存在一些编码魔术。
我的最终目标是从dotnet访问Matlab代码的大型信号处理库。 Matlab代码使用了大量的向量和数组,因此将它们带入和带出未管理的库是我的下一个障碍。
此致。
最佳答案
我不是mathlab用户,所以我可能错了,非常错!
获得等效的Linux .dll
您需要的是要从mathlab导出的运行时操作系统的正确共享库/对象。
从Mathlab获取 .so 导出库的指令
将您的MATLAB文件编译到共享库中(在UNIX上)
生成的 MyMath.so ,MyMath.exports,MyMath.h和MyMath.mlib,详细信息here
装订组件
确保在MyMath.dll文件旁边有MyMath.so文件(bin,应用程序数据或需要的位置)
自定义“NativeLibraryLoader”可用于加载基于GIT用户编写的基于OS的不同共享lib文件,因为.net核心没有任何(link)。我会说有点复杂,但这是您的选择。
可以使用[DllImport]!
[DllImport("MyMath")]
[DllImport("MyMath.dll")]
csproj中的配置图
<configuration>
<dllmap dll="MyMath.dll" target="MyMath.so" />
</configuration>