2008-09-15 5 views
5

Tengo una interfaz que he definido en C++ que ahora necesita implementarse en C#. ¿Cuál es la mejor manera de hacerlo? No quiero utilizar COM en absoluto en mi definición de interfaz. La forma en que lo he resuelto ahora es tener dos definiciones de interfaz, una en C++ y otra en C#. Luego expongo las interfaces C# como un servidor COM. Esta fue mi aplicación que está escrita en C++ puede llamar a C#. ¿Hay alguna forma en que pueda evitar tener que definir mi implementación en C++ y C#?Defina una interfaz en C++ que necesita implementarse en C# y C++

Respuesta

3

Si está dispuesto a usar C++/CLI para su código administrado en lugar de C#, entonces puede simplemente consumir la definición nativa de la interfaz C++ directamente a través del archivo de encabezado. Lo fácil que será dependerá exactamente de lo que contenga su interfaz. El caso más simple es algo que podría usar de C.

Mire Marcus Heege's Expert C++/CLI: .NET for Visual C++ Programmers, para obtener mucha información útil sobre cómo mezclar C++ nativo y administrado. en la red.

+0

También me gustaría agregar aquí que C++/CLI en acción por Nishant Sivakumar es un gran recurso para entender cómo conectar C++ a C#. – Juba

1

¿Por qué no quieres usar COM?

Esto hubiera sido mi sugerencia. La interoperabilidad COM ha funcionado muy bien para mí, y he usado objetos COM e interfaces en C# (simplemente referencia el objeto COM y el wrapper invocable en tiempo de ejecución se crea automáticamente). Del mismo modo, marcar una clase C# como "Registrarse para la interoperabilidad COM" ha funcionado al revés.

1

Escriba la interfaz en C++ y use macros para que se vea como un archivo de cabecera cpp estándar en UNIX y como un archivo IDL en Windows (si esto no funciona, siempre puede escribir un script python/ruby ​​para generar el IDL del archivo de encabezado C++).

Compila el IDL para generar un typelib. Utilice el importador de TypeLib para generar las definiciones de interfaz para C# e implemente las interfaces allí.

1

Escriba la interfaz en IDL y use una herramienta para compilar la interfaz con el idioma de destino. Es posible que encuentre punteros para esto cuando busque en CORBA, que estaba relacionado con la interconexión entre idiomas.

/Allan

0

Usted no menciona la versión de .NET que está utilizando, pero algo que ha funcionado para mí en el uso de Visual Studio .NET 2003 es proporcionar una delgada C# envoltorio sobre la puesta en práctica de pimpled la verdadera clase C++:

public __gc class MyClass_Net { 
public: 
    MyClass_Net() 
     :native_ptr_(new MyClass()) 
    { 
    } 
    ~MyClass_Net() 
    { 
     delete native_ptr_; 
    } 

private: 
    MyClass __nogc *native_ptr_; 
}; 

Obviamente, uno preferiría utilizar un shared_ptr Boost allí, pero nunca podría llegar a jugar bien con V.NET 2003 ...

Métodos simplemente con interés la los métodos subyacentes de C++ a través del puntero. Los argumentos del método pueden tener que convertirse. Por ejemplo, para llamar a un método C++ que toma una cadena, el método C# probablemente debería tomar un System.String (System :: String en C++ administrado). Tendría que usar System :: Runtime :: InteropServices :: Marshal :: StringToHGlobalAnsi() para hacer eso.

Una cosa buena acerca de este enfoque es que debido a que Managed C++ es un lenguaje .NET, se puede exponer a los usuarios como propiedades (__property). Incluso puedes exponer atributos, muy parecido a C#.

1

El otro enfoque es utilizar una API 'plana', estilo C. También puede usar extern "C" para evitar sobrecargas accidentales. Utilice un archivo DEF para nombrar explícitamente las funciones exportadas, por lo que definitivamente no están decoradas de ninguna manera (las funciones C++ están 'decoradas' con una codificación de los tipos de parámetros en la tabla de exportación).

En x86, tenga cuidado con las convenciones de llamadas. Probablemente sea para declarar explícitamente el uso de __stdcall o __cdecl. Debido a que P/Invoke se usa principalmente para invocar las API de Windows, de forma predeterminada es StdCall, pero C y C++ están por defecto en cdecl, porque eso admite varargs.

Recientemente envolví la interfaz COM IRapiStream en una interfaz plana C ya que .NET parecía estar tratando de convertir el IStream en un almacenamiento, que falló con el error STG_E_UNIMPLEMENTEDFUNCTION.

2

Swig es una gran herramienta para envolver clases de C++ en otros lenguajes como C#.

Cuestiones relacionadas