Pregunta

Tengo una interfaz que he definido en C++, que ahora necesita ser implementado en C#.¿Cuál es la mejor manera de ir sobre esto?No quiero usar COM a todos en mi definición de interfaz.La manera en que yo lo he solucionado con esto en este momento es tener dos definiciones de interfaz, uno en C++ y uno en C#.Yo, a continuación, exponer el C# interfaces como un servidor COM.Este fue mi aplicación que está escrito en C++ puede llamar en C#.Existe de todos modos puedo evitar tener que definir mi aplicación en C++, así como C#?

¿Fue útil?

Solución

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

Echa un vistazo a Marcus Heege del Experto en C++/CLI:.NET Visual para Programadores C++ , para una gran cantidad de información útil sobre la mezcla de nativos y de C++ administrado en .NET.

Otros consejos

Trago es una gran herramienta para el envasado de clases de C++ en otros lenguajes, como C#.

Por qué no quieres para uso COM?

Este hubiera sido mi sugerencia.Interoperabilidad COM ha trabajado muy bien para mí, y he usado los objetos COM y las interfaces en C# (referencia simplemente el objeto COM y el tiempo de ejecución de callable wrapper se crea automáticamente).Del mismo modo, que marca una clase de C# como "Registrar para interoperabilidad COM" ha trabajado de la otra manera alrededor.

Escribir la interfaz en C++ y el uso de macros para hacer que se vea como un estándar cpp archivo de encabezado en UNIX y como un archivo IDL en windows (Si esto no funciona, siempre puedes escribir un python/ruby script para generar el IDL de C++ archivo de encabezado).

Compilar el IDL para generar una biblioteca de tipos.Uso de la biblioteca de tipos Importador para generar las definiciones de interfaz para C# e implementar las interfaces de allí.

Escribir la interfaz IDL y el uso de una herramienta para recopilar la interfaz para el idioma de destino.Usted puede encontrar los punteros para esto cuando se mira en CORBA que se ocupa de la cruz-idioma de la interfaz.

/Allan

El otro enfoque es el uso de un 'plano', C-estilo de la API.Usted podría utilizar extern "C" para evitar la sobrecarga accidental.El uso de un archivo DEF explícitamente el nombre de las funciones exportadas, así que definitivamente no es decoradas en cualquier forma (a funciones de C++ son 'decorado' con una codificación de los tipos de parámetro en la tabla de exportación).

En x86, tenga cuidado de convenciones de llamada.Probablemente para declarar explícitamente el uso de __stdcall o __cdecl.Porque P/Invoke es, principalmente, se utiliza para llamar a las Api de Windows, por defecto StdCall, pero C y C++ por defecto para cdecl, debido a que soporta varargs.

Recientemente he envuelto la interfaz COM IRapiStream en un plano C interfaz .NET parecía estar tratando de convertir el IStream en un área de almacenamiento, que falló con el error STG_E_UNIMPLEMENTEDFUNCTION.

No mencionar que la versión de .NETA que estás usando, pero algo que ha funcionado para mí en el uso de Visual Studio .NET 2003 es proporcionar una fina C# envoltura alrededor de la purpúreo de la implementación de la verdadera clase de 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 prefiere el uso de un Impulso shared_ptr allí, pero nunca pude conseguir que jugar muy bien con V.NET 2003...

Métodos remite simplemente a la de C++ subyacente métodos a través del puntero.Los argumentos del método puede ser convertido.Por ejemplo, para llamar a un método de C++ que toma una cadena, el método de C# probablemente debería adoptar un Sistema.La cadena del Sistema::String en C++Administrado).Usted tendría que usar el Sistema::tiempo de ejecución::InteropServices::Mariscal::StringToHGlobalAnsi() para hacerlo.

Una cosa buena acerca de este enfoque es porque Managed C++ es un .NET lenguaje, se llega a exponer los descriptores de acceso como de las propiedades de (__de la propiedad).Incluso puede exponer atributos, igual que en C#.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top