Определите интерфейс в C ++, который должен быть реализован в C # и C ++ - PullRequest
5 голосов
/ 15 сентября 2008

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

Ответы [ 7 ]

4 голосов
/ 15 сентября 2008

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

Взгляните на Marcus Heege Expert C ++ / CLI: .NET для программистов на Visual C ++ , где содержится много полезной информации о смешивании собственного и управляемого C ++ в .NET.

2 голосов
/ 18 сентября 2008

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

1 голос
/ 16 сентября 2008

Другой подход заключается в использовании «плоского» 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.

1 голос
/ 15 сентября 2008

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

/ Allan

1 голос
/ 15 сентября 2008

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

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

1 голос
/ 15 сентября 2008

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

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

0 голосов
/ 16 сентября 2008

Вы не упоминаете, какую версию .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_;
};

Очевидно, что здесь предпочтительнее использовать Boost shared_ptr, но я никогда не смогу заставить их хорошо играть с V.NET 2003 ...

Методы просто перенаправляют на базовые методы C ++ через указатель. Аргументы метода могут быть преобразованы. Например, чтобы вызвать метод C ++, который принимает строку, метод C #, вероятно, должен взять System.String (System :: String в Managed C ++). Для этого вам понадобится System :: Runtime :: InteropServices :: Marshal :: StringToHGlobalAnsi ().

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...