使用包含点的库在跨平台 (ubuntu/windows) 上调用 p/invoke

Calling p/invoke on cross platform (ubuntu/windows) with library that contains dots

我正在尝试用 C# 开发一个程序,它在 linux (ubuntu 18.04) 和 Windows 中构建和运行,它引用了一个 C++ 库(通过 p/invoke - dllimport).我的 dll 作为 EmbeddedResource 导入,但我也尝试过 None Include = "..."

我的 C++ dll/so 命名中有点,这让我很头疼。

如果我将我的文件重命名为没有点,它工作正常。当我添加点时,如果我不添加扩展名(即 windows 中的 .dll),我会得到一个 DllNotFoundException,显然我不想提及扩展名,因为我想要交叉编译它。

示例:

public const string DllImport = @"myLib110";

[DllImport(DllImport)]
public static extern IntPtr myFun(float[] input);

适用于 myLib110.dll

其中:

public const string DllImport = @"myLib1.1.0";

文件 myLib1.1.0.dll.

中断

另外:

public const string DllImport = @"myLib1.1.0.dll";

工作正常,但我想交叉编译,所以这不适用于 linux,我的 lib 是一个 .so 文件。

有 tips/suggestions 吗?我还尝试了大多数 DllImport 的附加输入参数,但没有任何运气。

按照@PavelAnikhouski 的建议,我尝试以 netcoreapp3.0 为目标,而不是像我之前所做的那样将 2.1 作为目标,并合并了找到的示例 here .

运行非常顺利,只有一个例外(双关语不是故意的):

当 运行 我的单元测试时,我从第二个单元测试和 NativeLibrary.SetDllImportResolver 方法开始一直得到 InvalidOperationException。正如微软在他们的 documentation 中提到的 class:

Only one resolver can be registered per assembly. Trying to register a second resolver fails with an InvalidOperationException.

但我不明白为什么我的单元测试会这样。我所做的解决方法是将 try/catch 包装在 public static void Register(Assembly assembly) (Map.cs) 中。具体来说:

try
{
    NativeLibrary.SetDllImportResolver(assembly, MapAndLoad);
}
catch (Exception e)
{
    Console.WriteLine(e);
}

对我有用。