Rasmus Tollund
Rasmus Tollund

Reputation: 65

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

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

Answers (1)

Rasmus Tollund
Rasmus Tollund

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

Related Questions