我试图从运行在Linux容器上的C#(.NET Core)调用使用MathWorks MATLAB Compiler 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
MyMath.h
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以获得潜在的双重收益,我只是还没有发现那种特别的信息。
将.m文件编译成.NET库和COM对象时,我已经成功了。我不认为我可以在Linux上使用这两个库中的任何一个,因为每个操作系统的二进制加载/链接格式不同。当在COM对象中调用该方法时,我能够将IntPtr直接转换为double,那么在后台一定会有一些编组魔术。
我的最终目标是从dotnet访问大型的matlab代码信号处理库。 matlab代码使用了大量的向量和数组,因此将它们放入未管理的库中是我的下一个障碍。
最诚挚的问候。
答案 0 :(得分:0)
我不是mathlab用户,所以我可能错了,非常错了!
您需要的是要从mathlab导出的运行时操作系统的正确共享库/对象。
- Windows: .dll =动态链接库
- Linux: .so =共享对象[.Linux的.net核心黄油和面包]
从Mathlab获取 .so 导出库的指令 将您的MATLAB文件编译到共享库中(在UNIX上)
mcc -t -L C -W MyMath-T链接:lib haveSomePi.m libmmfile.mlib
生成的 MyMath.so ,MyMath.exports,MyMath.h和MyMath.mlib ,更多详细信息here >
确保在MyMath.dll文件(bin,应用程序数据或需要的位置)旁边有MyMath.so文件
自定义“ NativeLibraryLoader”可用于加载基于GIT用户编写的基于OS的不同共享lib文件,因为.net核心没有任何(link)。我会说有点复杂,但这是您的选择。
可以使用[DllImport]!
[DllImport("MyMath")]
[DllImport("MyMath.dll")]
csproj中的配置映射
<configuration>
<dllmap dll="MyMath.dll" target="MyMath.so" />
</configuration>
答案 1 :(得分:0)
我认为这里主要要担心的是
C共享库
不是C# ...
相反,您应该这样做
.NET组装
https://in.mathworks.com/help/compiler_sdk/gs/create-a-dotnet-application-with-matlab-code.html
请务必注意,也不支持.NET Core,并且您必须将项目更改为“经典” .NET Framework(如果我没记错的话,至少应为4.x)