В рантайме Mono есть немало средств для взаимодействия с кодом на не .NET языках, но никогда не было ничего вменяемого для взаимодействия с кодом на C++.
Но это вскоре изменится благодаря работе Алекса Коррадо, Андрэа Гайта и Зольтана Варга.
Вкратце, новая технология позволяет разработчикам C#/.NET:
Легко и прозрачно использовать классы C++ из C# или любого иного .NET языка
Создавать экземпляры классов C++ из C#
Вызывать методы классов C++ из кода на C#
Вызывать инлайн-методы C++ из кода на C# (при условии, что библиотека скомпилирована с флагом -fkeep-inline-functions или если вы скомпилируете дополнительную библиотеку с их реализациями)
Наследовать классы C++ из C#
Переопределять виртуальные методы классов C++ методами на C#
Использовать экземпляры таких смешанных C++/C# классов как в коде на C#, так и в коде на C++
CXXI (прим. пер.: читается как «sexy») это результат двухмесячной работы под эгидой Google's Summer of Code с целью улучшить взаимодействие Mono с кодом на C++.
Альтернативы
Напоминаю, что Mono предоставляет несколько механизмов взаимодействия с кодом на не .NET языках, большей частью унаследованные из ECMA-стандарта. Эти механизмы включают:
Двухсторонняя технология «Platform Invoke» (P/Invoke), позволяющая управляемому коду (C#) вызывать функции из неуправляемых библиотек, а коду этих библиотек делать callback'и обратно в управляемый код.
COM Interop позволяющий коду, выполняющемуся в Mono прозрачно вызывать неуправляемый код на C или C++ до тех пор пока этот код соблюдает некоторые конвенции COM (конвенции эти довольно простые: стандартная «разметка» vtable, реализация методов Add, Release и QueryInterface, а так же использование стандартного набора типов, которые могут быть отмаршалены между Mono и COM-библиотекой).
Общая технология перехвата вызовов, позволяющая перехватить вызов метода объекта и дальше самостоятельно разбираться с тем, что с ним делать.
Но когда дело доходит до того чтобы использовать в C# объекты C++, выбор остаётся не очень-то обнадёживающий. Для примера, предположим что вы хотите из C# использовать следующий класс C++:
class MessageLogger {
public:
MessageLogger (const char *domain);
void LogMessage (const char *msg);
}
Одним из способов предоставить этот класс коду на C# — обернуть его в COM-объект. Это может сработать для некоторых высокоуровневых объектов, но процесс оборачивания весьма нудный и рутинный. Посмотреть, как выглядит это неинтересное занятие можно тут.
Другой вариант — наклепать переходников, которые потом можно будет вызвать через P/Invoke. Для представленного выше класса выглядеть они будут примерно так:
/* bridge.cpp, компилируется в bridge.so */
MessageLogger *Construct_MessageLogger (const char *msg)
{
return new MessageLogger (msg);
}
void LogMessage (MessageLogger *logger, const char *msg)
{
logger->LogMessage (msg);
}
Часть на C# выглядит так:
class MessageLogger {
IntPtr handle;
[DllImport ("bridge")]
extern static IntPtr Construct_MessageLogger (string msg);
public MessageLogger (string msg)
{
handle = Construct_MessageLogger (msg);
}
[DllImport ("bridge")]
extern static void LogMessage (IntPtr handle, string msg);
public void LogMessage (string msg)
{
LogMessage (handle, msg);
}
}
Read more: Habrahabr.ru
QR: