DllNotFoundException при использовании DllImport в C # на простом общем объектном файле C - PullRequest
0 голосов
/ 06 мая 2019

Я пытаюсь запустить код C из C #, но я получаю DllNotFoundException, даже если файл там.У меня есть файл C "test.c" со следующим кодом:

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

Я скомпилирую это в библиотеку общих объектов с помощью команды:

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

Этот файл добавляется впроект, и я установил его параметры «всегда копировать», так что это находится в директиве сборки.Код 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));
        }
    }
}

Я запускаю его на Linux с Mono и целевой версией фреймворка v4.7.2.Я получаю следующую ошибку:

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" и все другие способы.Использование File.Exists("libtest.so") возвращает true, указывая, что он может найти файл во время выполнения в каталоге.

1 Ответ

1 голос
/ 07 мая 2019

Я нашел решение. Запуск исполняемого файла с

$ 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
...