在 C# 中对简单 C 共享对象文件使用 DllImport 时出现 DllNotFoundException

DllNotFoundException when using DllImport in C# on simple C shared object file

我正在尝试从 C# 运行 C 代码,但我得到一个 DllNotFoundException,即使该文件存在。我有一个包含以下代码的 C 文件 "test.c":

int test(int a) {
    return a + 10;
}

我使用以下命令将其编译成共享对象库:

gcc test.c -c -shared -fPIC -o libtest.so

此文件已添加到项目中,我已将其设置为 "copy always",因此它位于构建指令中。 C# 代码如下所示:

using System;
using System.Runtime.InteropServices;

namespace CTest {
    class Program {
        [DllImport("test")]
        public static extern int test(int i);

        public static void Main(string[] args) {
            Console.WriteLine(test(1));
        }
    }
}

我运行使用 Mono 和框架目标版本 v4.7.2 在 linux 上安装它。我收到以下错误:

Unhandled Exception:
System.DllNotFoundException: test
  at (wrapper managed-to-native) CWrapperTestFramework.Program.test(int)
  at CWrapperTestFramework.Program.Main (System.String[] args) [0x00001] in <827de23517bb4c0eb7fed2eff92099aa>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.DllNotFoundException: test
  at (wrapper managed-to-native) CWrapperTestFramework.Program.test(int)
  at CWrapperTestFramework.Program.Main (System.String[] args) [0x00001] in <827de23517bb4c0eb7fed2eff92099aa>:0 

我也尝试过导入 "libtest.so" 以及所有其他方式。 Using File.Exists("libtest.so") returns true,表示可以在目录中找到运行时间的文件。

我找到了解决方案。 运行 带有

的可执行文件
$ MONO_LOG_LEVEL="debug" MONO_LOG_MASK="dll" mono CTest.exe

告诉我那个only ET_DYN and ET_EXEC can be loaded。 运行

readelf -h libtest.so

告诉我 Type: REL (Relocatable file),而应该是 DYN (Shared Object File)。我虽然 -shared 编译选项做到了这一点,但显然我必须用 -flinker-output=dyn 指定它。所以必须这样编译

gcc test.c -o test.o -fPIC -c
gcc test.o -o libtest.so -flinker-output=dyn -shared