Если Вы готовы использовать C++ / CLI для Вашего управляемого кода вместо C#, то можно просто использовать собственное определение интерфейса C++ непосредственно через заголовочный файл. То, насколько легкий это будет, будет зависеть от точно, что находится в Вашем интерфейсе - самый простой случай - что-то, что Вы могли использовать от C.
Смотрите на Эксперта Marcus Heege C++ / CLI:.NET для Программистов Visual C++, для большой полезной информации о смешивании собственного и управляемого С++ в.NET.
Большой глоток является большим инструментом для обертывания классов C++ на других языках как C#.
Почему Вы не хотите использовать COM?
Это было бы моим предложением. Взаимодействующий с COM работал действительно хорошо на меня, и я использовал COM-объекты, и интерфейсы в C# (просто ссылаются на COM-объект, и обертка вызовов среды выполнения создается автоматически). Так же отмечая класс C# как "Регистр для взаимодействующего с COM" работал наоборот.
Запишите интерфейс в C++ и используйте макросы, чтобы заставить его быть похожим на стандарт cpp заголовочный файл на UNIX и как файл IDL на окнах (Если это не удается, можно всегда писать сценарий Python/рубина для генерации IDL от заголовочного файла C++).
Скомпилируйте IDL для генерации typelib. Используйте Средство импорта TypeLib, чтобы генерировать интерфейсные определения для C# и реализовать интерфейсы там.
Запишите интерфейс в IDL и используйте инструмент для компиляции интерфейса в выходной язык. Вы могли бы найти указатели для этого при изучении CORBA, который касался межъязыкового взаимодействия через интерфейс.
/Allan
Другой подход должен использовать 'плоский', C-стиль API. Вы могли бы также использовать extern "C"
предотвратить случайную перегрузку. Используйте файл DEF для явного именования экспортируемых функций, таким образом, они определенно не украшены всегда (функции C++ 'украшены' кодированием типов параметра в таблице экспорта).
На x86 остерегайтесь соглашений о вызовах. Это должно, вероятно, явно объявить использование __stdcall
или __cdecl
. Поскольку P/Invoke, прежде всего, используется для вызова Windows APIs, он принимает значение по умолчанию к StdCall, но C и значение по умолчанию C++ к cdecl, потому что это поддерживает varargs.
Я недавно перенес COM-интерфейс IRapiStream
в плоском интерфейсе C, поскольку.NET, казалось, пыталась преобразовать IStream в устройство хранения данных, которое перестало работать с ошибкой STG_E_UNIMPLEMENTEDFUNCTION
.
Вы не упоминаете, какую версию.NET Вы используете, но что-то, что это работало на меня в использовании Visual Studio.NET, который 2003 должен обеспечить тонкой обертке C# вокруг прыщавой реализации реального класса C++:
public __gc class MyClass_Net {
public:
MyClass_Net()
:native_ptr_(new MyClass())
{
}
~MyClass_Net()
{
delete native_ptr_;
}
private:
MyClass __nogc *native_ptr_;
};
Очевидно, можно было бы предпочесть использовать Повышение shared_ptr там, но я никогда не мог заставлять их играть приятно с V.NET 2003...
Методы просто передают базовым методам C++ через указатель. Аргументы метода, вероятно, придется преобразовать. Например, для вызова метода C++, который берет строку метод C# должен, вероятно, взять Систему. Строка (Система:: Строка в Управляемом С++). Необходимо было бы использовать Систему:: Время выполнения:: InteropServices:: Маршал:: StringToHGlobalAnsi (), чтобы сделать это.
Одна хорошая вещь об этом подходе состоит в том, потому что Управляемый С++ является языком.NET, Вы добираетесь для представления средств доступа как свойств (__ свойство). Можно даже выставить атрибуты, очень как в C#.