#c_sharp #c #gcc #net_core
Код на Си: #includevoid main() { printf("Hello world\n"); } Команда сборки этого кода в модуль main.dll для Терминала Linux: gcc main.c -o main.dll Вызывающий код на C# (сборка dllimportc.dll): using System; using System.Runtime.InteropServices; namespace netcore { class Program { static void Main() { Console.WriteLine("Hello World!"); main(); Console.ReadLine(); } [DllImport("main.dll", EntryPoint = "main", CallingConvention = CallingConvention.Cdecl)] public static extern void main (); } } На вызове main(); возникает исключение: Exception has occurred: CLR/System.EntryPointNotFoundExceptionAn unhandled exception of type 'System.EntryPointNotFoundException' occurred in dllimportc.dll: 'Unable to find an entry point named 'main' in shared library 'main.dll'.' at dllimportc.Program.main() at dllimportc.Program.Main() Как откорректировать программу, чтобы .Net Core в консольном приложении находил точку входа и Hello World выводился два раза без исключений? ОБНОВЛЕНО В коде выше библиотека в Linux создавалась неправильно. Правильные инструкции можно подсмотреть здесь - Создание библиотеки в Linux. Для Ubuntu 18.04 LTS пришлось добавить возвращаемый тип в функцию на Си и вместо команды ldconfig -v -n . использовать ldconfig -v -n -l main.so.0.0 ОБНОВЛЕНО 06.10.2018 Можно проще: использовать для сборки только команду gcc -o main.so -s -shared -O2 main.c -m64 Затем подкладываем main.so в bin, и в C# для .Net Core всё просто: [DllImport("main.so")] public static extern void main ();
Ответы
Ответ 1
Для подключения через extern внешний код должен быть собран как библиотека. Для этого можно в Linux использовать для сборки команду (предварительно должен быть установлен компилятор GCC, если его не было в системе): gcc -o main.so -s -shared -O2 main.c -m64 Для библиотеки наличие функции main не обязательно. Исходный файл на чистом Си main.c эта команда скомпилирует в библиотеку (за это отвечает флаг shared) main.so (в Linux рекомендуется называть библиотеки с префиксом lib и давать им расширение so). Флаги s и O2 отвечают за оптимизацию для продуктива, а флаг m64 настраивает принудительную сборку для платформы x64. Затем подкладываем main.so в подпапку папки bin, где лежит собранный файл вашего проекта, и в C# для .Net Core всё просто: [DllImport("main.so")] public static extern void main (); Чтобы увидеть текстовое сообщение из внешней библиотеки, можно собрать проект .Net Core как консольное приложение, сделать вызов main() как обычного метода C# в теле вашей программы и запустить собранный проект из Терминала.
Комментариев нет:
Отправить комментарий