c# - Dotnet 核心的 DllImport 返回当前 DLL 的 DLLNotFoundException

标签 c# c interop

在过去的几天里,我一直在尝试与 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/

相关文章:

c# - XSLt.transform 给我 ""

c - 死亡时慢慢变黑

C11 VLA 矩阵访问

C# 以编程方式访问 Excel 宏

c# - 在 WPF 中绑定(bind)两个依赖属性

c# - 计算折扣价

c# - 如何绘制平滑/圆角/曲线图? (C#)

c - 如果 malloc 通过 gdb 返回 NULL,如何设置条件断点

java - 从 C++ 头文件生成 Java 接口(interface)

interop - 为什么使用 BIND(C, NAME ="name") 属性时我的 fortran 函数没有导出