在linux上从dotnet core调用matlab共享库

Den*_*unn 10 linux matlab-compiler .net-core

我正在尝试调用使用在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
Run Code Online (Sandbox Code Playgroud)

MyMath.h

extern LIB_MyMath_C_API bool MW_CALL_CONV mlfHaveSomePi(int nargout, mxArray** hal);
Run Code Online (Sandbox Code Playgroud)

MyMathWrapper.cs

[DllImport("MyMath.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void mlfHaveSomePi(int nargout, ref IntPtr hal);
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

预期的结果是测试方法中的断言通过.它失败是因为尝试将IntPtr强制转换为double在这种情况下没有意义.我确信有一种方法可以取消引用IntPtr以获得底层的双重,我只是没有找到特定的信息块.

将.m文件编译成.NET库和COM对象时,我成功了.我不认为我可以在Linux上使用这些库中的任何一个,因为每个操作系统的二进制加载/链接格式不同.在COM对象中调用方法时,我能够直接将IntPtr强制转换为double,必须在后台运行一些编组魔法.

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

我的最终目标是从dotnet访问matlab代码的大型信号处理库.matlab代码使用了很多向量和数组,因此将这些进出非文件库是我的下一个障碍.

最好的祝福.

Sil*_*mor 0

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


获取 Linux .dll 等效项

您需要的是要从 mathlab 导出的运行时操作系统的正确共享库/对象。

  • Windows:.dll = 动态链接库
  • Linux:.so = 共享对象 [Linux 的 .net core 黄油和面包]

从 mathlab获取.so导出 lib 的说明 将 MATLAB 文件编译到共享库(在 UNIX 上)

mcc -t -LC -W MyMath-T 链接:lib haveSomePi.m libmmfile.mlib

生成MyMath.so、 MyMath.exports、MyMath.h 和 MyMath.mlib,更多详细信息请参见此处


装订组件

确保 MyMath.dll 文件旁边有 MyMath.so 文件(bin、应用程序数据或需要的位置)

自定义“NativeLibraryLoader”可用于加载基于操作系统的不同共享库文件,由 GIT 用户编写,因为 .net core 没有任何共享库文件(链接)。我想说有点过于复杂,但这是你的选择。

可以用[DllImport]代替!

  1. DllImport 不带扩展名,在 Windows 和 Linux 上受支持,MAC 将为目标平台导入适当的库。
 [DllImport("MyMath")] 
Run Code Online (Sandbox Code Playgroud)
  1. 使用 < dllmap /> 将导入库名称映射到目标平台库名称。对于 MyMath.dll,相应的 Linux .so 应该是 MyMath.so(更多信息请参见此处
 [DllImport("MyMath.dll")] 
Run Code Online (Sandbox Code Playgroud)

csproj 中的配置映射

<configuration>
  <dllmap dll="MyMath.dll" target="MyMath.so" />
</configuration>
Run Code Online (Sandbox Code Playgroud)