Код на Си:
#include <stdio.h>
void 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 ();
Для подключения через 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# в теле вашей программы и запустить собранный проект из Терминала.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости