2008-09-15 3 views
5

У меня есть интерфейс, который я определил на C++, который теперь должен быть реализован на C#. Каков наилучший способ сделать это? Я не хочу использовать COM вообще в моем определении интерфейса. То, как я решил это прямо сейчас, состоит в том, чтобы иметь два определения интерфейса: один на C++ и один на C#. Затем я выставляю интерфейсы C# в качестве COM-сервера. Это мое приложение, написанное на C++, может вызывать на C#. В любом случае я могу избежать необходимости определять свою реализацию на C++, а также на C#?Определить интерфейс в C++, который должен быть реализован в C# и C++

ответ

3

Если вы хотите использовать C++/CLI для управляемого кода вместо C#, то вы можете просто использовать собственное определение интерфейса C++ непосредственно через файл заголовка. Как легко это будет зависеть от того, что именно в вашем интерфейсе - простейший случай - это то, что вы могли бы использовать от C.

Посмотрите на Expert C++/CLI: .NET for Visual C++ Programmers от Marcus Heege, чтобы получить полезную информацию о смешивании родного и управляемого C++ в .NET.

+0

Также можно добавить, что C++/CLI в действии Nishant Sivakumar - отличный ресурс для понимания того, как подключить C++ к C#. – Juba 2011-02-04 17:39:03

1

Почему вы не хотите использовать COM?

Это было бы мое предложение. COM-взаимодействие работало очень хорошо для меня, и я использовал COM-объекты и интерфейсы на C# (просто ссылайтесь на COM-объект, и оболочка, вызывающая вызов, создается автоматически). Аналогично, маркировка класса C# как «Регистрация для COM-взаимодействия» работала наоборот.

1

Напишите интерфейс на C++ и используйте макросы, чтобы он выглядел как стандартный заголовочный файл cpp в UNIX и как IDL-файл в окнах (если это не сработает, вы всегда можете написать скрипт python/ruby ​​для генерации IDL из файла заголовка C++).

Скомпилируйте IDL для создания typelib. Используйте TypeLib Importer для генерации определений интерфейса для C# и реализации интерфейсов.

1

Напишите интерфейс в IDL и используйте инструмент для компиляции интерфейса на целевой язык. Вы могли бы найти указатели на это, глядя на CORBA, который касался межязыкового интерфейса.

/Allan

0

Вы не упоминаете, какую версию .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# должен, вероятно, взять System.String (System :: String в управляемом C++). Для этого вам нужно использовать System :: Runtime :: InteropServices :: Marshal :: StringToHGlobalAnsi().

Одна из приятных вещей в этом подходе заключается в том, что Managed C++ - это язык .NET, вы получаете доступ к аксессуарам в качестве свойств (__property). Вы даже можете выставлять атрибуты, очень похожие на C#.

1

Другой подход заключается в использовании «плоского», C-стиля API. Вы можете использовать extern "C" для предотвращения случайной перегрузки. Используйте DEF-файл, чтобы явно указать экспортированные функции, поэтому они определенно не оформлены каким-либо образом (функции C++ «украшены» кодировкой типов параметров в таблице экспорта).

На x86, остерегайтесь вызывать соглашения. Возможно, явно объявить использование __stdcall или __cdecl. Поскольку P/Invoke в основном используется для вызова API Windows, по умолчанию используется StdCall, но C и C++ по умолчанию - cdecl, потому что это поддерживает varargs.

Недавно я обернул COM-интерфейс IRapiStream в плоском интерфейсе C, поскольку .NET, казалось, пытался конвертировать IStream в хранилище, которое не удалось с ошибкой STG_E_UNIMPLEMENTEDFUNCTION.

2

Swig - отличный инструмент для обертывания классов C++ на других языках, таких как C#.