Reputation: 65
I am trying to run C code from C#, but I get a DllNotFoundException even though the file is there. I have a C file "test.c" with the following code:
int test(int a) {
return a + 10;
}
I compile this into a shared object library with the command:
gcc test.c -c -shared -fPIC -o libtest.so
This file gets added to the project, and I have set it's settings to "copy always", so that it is in the build directive. The C# code looks like this:
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));
}
}
}
I am running it on linux with Mono and framework target version v4.7.2. I get the following error:
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
I have tried importing "libtest.so" too and all other sorts of ways. Using File.Exists("libtest.so")
returns true, indicating that it can find the file on runtime in the directory.
Upvotes: 1
Views: 1536
Reputation: 65
I found the solution. Running the executable with
$ MONO_LOG_LEVEL="debug" MONO_LOG_MASK="dll" mono CTest.exe
told me that that only ET_DYN and ET_EXEC can be loaded
. Running
readelf -h libtest.so
told me that Type: REL (Relocatable file)
, when it should be DYN (Shared Object File)
. I though the -shared
compile option did this, but apparently I had to specify it with -flinker-output=dyn
. So it has to be compiled like this
gcc test.c -o test.o -fPIC -c
gcc test.o -o libtest.so -flinker-output=dyn -shared
Upvotes: 1