从Linux上的dotnet核心调用Matlab共享库

时间:2019-01-26 14:06:22

标签: linux .net-core matlab-compiler

我试图从运行在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,那么在后台一定会有一些编组魔术。

  1. DLLImport语句的方法签名正确吗?我可以将mxArray **映射到IntPtr吗?
  2. 如何从IntPtr获得双倍?将一块内存复制到托管字节数组中并进行强制转换?

我的最终目标是从dotnet访问大型的matlab代码信号处理库。 matlab代码使用了大量的向量和数组,因此将它们放入未管理的库中是我的下一个障碍。

最诚挚的问候。

2 个答案:

答案 0 :(得分:0)

我不是mathlab用户,所以我可能错了,非常错了!


获取等效的Linux .dll

您需要的是要从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]!

  1. 不带扩展名的DllImport(在Windows和Linux上受支持),MAC将为目标平台导入适当的库。
 [DllImport("MyMath")] 
  1. 使用<dllmap />将导入库名称映射到目标平台库名称。对于MyMath.dll,相应的Linux .so应该是MyMath.so(more here
 [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)