在过去的几天里,我一直在尝试与 Linux 上的 dotnet core 中的 C 库(为 ARM 平台构建)进行交互。我想做的就是调用一个简单的函数,它(本质上)返回一个字符串。
但是,我没有在 C# 中使用 DLLImport
或互操作的经验,而且我很挣扎。
C 代码看起来像(当我使用工作平台时使用替换名称):
int version(int argc, char *argv[])
{
return READ_DATA(0,
version, //callbackfunction
"version: 0x%04x\n"); //formatting string
}
public class Board
{
private Interop_Commands _commands = new Interop_Commands();
public string GetVersion()
{
return _commands.GetVersion();
}
}
internal class Interop_Commands
{
public const string LIBRARYPATH = "libname";
[DllImport(LIBRARYPATH,CharSet=CharSet.Unicode, CallingConvention =CallingConvention.Cdecl)]
public static extern int version(int argc, StringBuilder argv);
public string GetVersion()
{
var sb = new StringBuilder();
Console.WriteLine($"Calling {nameof(version)}");
version(0, sb);
Console.WriteLine($"Called {nameof(version)}, got: {sb.ToString()}");
return sb.ToString();
}
}
与调用类(主要用于这个非常简单的概念验证/试用代码):
static void Main(string[] args)
{
Console.WriteLine("Getting Version from board..");
var board = new Board();
Console.WriteLine(board.GetVersion());
Console.WriteLine("done");
Console.ReadLine();
}
文件夹结构为(简化):
folder
|--> Dll/runtime
|--> libname (note no .so here, just libname)
任何帮助将不胜感激,我正在寻找有限的 C 导入/使用示例,并且还找到了如何在 dotnet core 中使用自定义库的有限示例。
编辑 1:
在@Sohaib Jundi的帮助下,我添加了extern
,因此签名现在是:(它不会使用extern“C”进行编译)
extern int version(int argc, char *argv[])
我不确定下一步要尝试什么。
但是 dotnet core 不会使用 x86 并将目标运行时设置为 linux-arm
进行发布,只会引发未知异常,日志文件也没有太大帮助。
如果我将编译后的库与之前的代码(AnyCPU
+ linux-arm
)一起使用,那么仍然会抛出DllNotFoundException
* 编辑 2:*
事实证明,我使用的原始无扩展文件似乎是引用静态库的可执行文件(最终编译为可执行文件)。重建我已经设法将静态库分开,但仍然得到相同的DllNotFoundException
。有谁知道 dotnet core 上 DllImport
的搜索过程是什么?
互操作/导入代码现在如下所示:
[DllImport("libname",
CallingConvention =CallingConvention.Cdecl,
EntryPoint= "version")]
public static extern int version(ref uint val);
静态库代码如下所示:
extern int version(uint32_t *);
最佳答案
经过一番尝试后,我设法找到了一个可以工作的示例。
请按照下列步骤操作:
1. 从 dll 中导出函数,即:将 extern "C"__declspec(dllexport)
添加到函数签名
2. 确保 dll 和您的 dotnet core 应用程序具有相同的体系结构。不要将 dotnet 核心保留为“任何 CPU”,强制其与 dll 具有相同的架构。 (项目属性 -> 构建 -> 平台目标 = x86 或 x64)
关于c# - Dotnet 核心的 DllImport 返回当前 DLL 的 DLLNotFoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56957459/