Вызов кода С# из С++
Мне нужно иметь возможность вызывать произвольные функции С# из С++. http://www.infoq.com/articles/in-process-java-net-integration предлагает использовать ICLRRuntimeHost:: ExecuteInDefaultAppDomain(), но это только позволяет мне вызывать методы, имеющие этот формат: int method(string arg)
Каков наилучший способ вызвать произвольные функции С#?
Ответы
Ответ 1
Скомпилируйте свой код на С++ с помощью флага /clr. С этим вы можете с легкостью вызвать любой .NET-код.
Например:
#include <tchar.h>
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
System::DateTime now = System::DateTime::Now;
printf("%d:%d:%d\n", now.Hour, now.Minute, now.Second);
return 0;
}
Учитывается ли это как "С++"? Ну, это явно не стандартный С++...
Ответ 2
Приложение C++ может вызывать функции в DLL-библиотеке С# несколькими способами.
- Использование C++/CLI в качестве промежуточной библиотеки DLL
- Обратный P/Invoke
-
Использование COM
- Использование хостинга CLR (
ICLRRuntimeHost::ExecuteInDefaultAppDomain()
)
-
Межпроцессное взаимодействие (МПК)
- Редактирование: размещение HTTP-сервера и вызов через HTTP-глаголы (например, API в стиле REST)
Ответ 3
Если вам неважно, скомпилирована ли ваша С++-программа (или ее часть) с помощью /clr, вы можете использовать С++/CLI для простого вызова любого .NET-кода (если вы добавите ссылку на него).
Попробуйте эту статью.
EDIT: хороший учебник
Другой маршрут - сделать ваш код С# открытым как COM.
Ответ 4
Самый простой способ - использовать COM-взаимодействие.
Ответ 5
Смотрите DllExport.
IOW: полная противоположность тому, как работает DllImport
.
https://github.com/3F/DllExport
Он имеет поддержку Windows, с кроссплатформенной поддержкой в работе.
Код С# (который мы называем из C++):
[DllExport]
public static int _add(int a, int b)
{
return a + b;
}
[DllExport]
public static bool saySomething()
{
DialogResult dlgres = MessageBox.Show(
"Hello from managed environment !",
".NET clr",
MessageBoxButtons.OKCancel
);
return dlgres == DialogResult.OK;
}
C++ код (который вызывает предыдущий код С#):
typedef int(__cdecl *_add)(int a, int b);
typedef bool(__cdecl *saySomething)();
auto pAdd = (_add)GetProcAddress(lib, "_add");
int c = pAdd(5, 7);
auto pSaySomething = (saySomething)GetProcAddress(lib, "saySomething");
bool dlgres = pSaySomething();
И видео на YouTube с демонстрацией в Управляемом & Неуправляемый; PInvoke; [Конари против DllExport]. Честно говоря, документация на порядок ниже идеальной, но не позволяйте этому отталкивать вас: видео на YouTube превосходны.
Этот проект вдохновлен другим проектом Роберта Гизеке, который имеет 220 000 загрузок на NuGet.
Интересный факт: некоторые библиотеки Python использовали это для реализации функциональности в сочетании C++ и С#.
И, наконец, спасибо Роберту Гизеке и Денису Кузьмину, блестящая, блестящая работа!
Ответ 6
Вы можете использовать COM вызываемую оболочку вокруг вашего кода на С#, скомпилированного в DLL.
Ответ 7
В качестве альтернативного подхода вы можете использовать Lua для создания объектов CLR, выполнения и возврата результатов.
Ответ 8
От Microsoft: Напишите собственный хост .NET Core для управления средой выполнения .NET из собственного кода.
IOW: вызвать С# из C++ в Windows и Linux.
На GitHub есть пример кода.
Этот пример кода является кроссплатформенным, он позволяет вызывать код С# в .NET Core из любого приложения C++ в Linux и Windows.
Честно говоря, это решение кажется довольно сложным по сравнению с другим ответом DllExport
. Код C++ выполняет большую работу по поиску ресурсов и точек входа и т.д. Одним из аргументов в пользу этого ответа может быть кроссплатформенность. Однако другой ответ DllExport
также кроссплатформенный и намного проще в использовании.