¿Cómo puedo llamar a C ++ / CLI desde C #?

Tengo una clase implementada en C ++ que es responsable del cálculo aritmético del progtwig y una interfaz que usa WPF. Proceso la entrada con C #, pero ¿cómo puedo usar mi clase de C ++?

He visto algunos comentarios sobre cómo hacer que una clase administrada de contenedor de C ++ interactúe con él, pero no sé por dónde empezar. Tampoco sé cómo iría a comstackrlo junto con el rest del código. Realmente no puedo encontrar un tutorial sobre esto, y las cosas que google muestra en C ++ administrado realmente no parecen útiles.

¿Hay algo por ahí para ayudarme? Esto no me parece irrazonable.

EDITAR intentó la solución m3rLinEz pero me está dando una BadImageFormatException, creo que es porque no se genera el archivo DLL. Hice todo lo que le dije, no sé qué pasó. ¿Algunas ideas?

Hay al menos tres formas de llamar al código no administrado desde el mismo proceso:

  1. C ++ / CLI
  2. Invocación de plataforma
  3. Envuelva su C ++ en un objeto COM

En el trabajo, usamos C ++ / CLI para esto, parece funcionar.

Crearía una biblioteca de vínculos dynamics estándar (no COM / gestionada) como se describe aquí y luego usaría el atributo DllImport (invocación de plataforma) en el código c # para acceder a las funciones exportadas.

El punto clave de ese artículo:

Tenga en cuenta el modificador __declspec (dllexport) en las declaraciones de métodos en este código. Estos modificadores permiten que el método sea exportado por el DLL para que pueda ser utilizado por otras aplicaciones. Para obtener más información, vea dllexport, dllimport.

Esta es una alternativa más ligera que una envoltura de interoperabilidad de COM real y evita problemas como el registro, etc. (la DLL simplemente puede colocarse en el directorio de la aplicación).

Otra alternativa es It Just Works (IJW). Esta es probablemente una mejor opción si ha administrado el código C ++ y necesita acceder a este desde otros lenguajes .NET. Pero esto es solo una opción si puede / feliz de convertir su C ++ no administrado a C ++ administrado.

Me mantendría alejado de P / Invoke, ya que es bastante lento en comparación con IJW (It Just Works). Este último le permite entrelazar sin problemas el c ++ administrado y no administrado. Todo lo que tiene que hacer es crear un ensamblado administrado de c ++, escribir una clase administrada que sea visible desde c # y llamar el código no administrado fuera de eso.

Uhm … OK. Tenía la impresión de que las llamadas de P / Invoke eran más lentas, y no lo son de manera hereditaria. Sin embargo, al tener un control explícito sobre la clasificación, puede hacer que su versión de C ++ / CLI tenga un mejor rendimiento en muchos de los casos.

Aquí está el artículo de Microsoft sobre ambos mecanismos:

http://msdn.microsoft.com/en-us/library/ms235282.aspx

Ventajas de IJW

  • No es necesario escribir declaraciones de atributos de DLLImport para las API no administradas que usa el progtwig. Solo incluya el archivo de encabezado y el enlace con la biblioteca de importación.
  • El mecanismo IJW es un poco más rápido (por ejemplo, los stubs IJW no necesitan verificar la necesidad de anclar o copiar elementos de datos porque el desarrollador lo hace explícitamente).
  • Ilustra claramente los problemas de rendimiento. En este caso, el hecho de que está traduciendo de una cadena Unicode a una cadena ANSI y de que tiene una asignación de memoria y desasignación de asistente. En este caso, un desarrollador que escriba el código usando IJW se daría cuenta de que llamar a _putws y usar PtrToStringChars sería mejor para el rendimiento.
  • Si llama a muchas API no administradas utilizando la misma información, organizarla una vez y pasar la copia ordenada es mucho más eficiente que reorganizar todas las veces.

También hay ventajas estéticas:

  • El código de C # se parece al código de C # sin ningún tipo de interoperabilidad.
  • No tiene que definir el atributo DLLImport , no tiene que definir ninguna estructura de datos (también con atributos específicos de p / invoke) que podría verse así:

    [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct DevMode {[MarshalAs (UnmanagedType.ByValTStr, SizeConst = 32)] public string dmDeviceName; }

  • No es necesario convertir todos los tipos de primitiva de parámetro en sus homólogos de .NET (hay una tabla en esta página que enumera cómo los tipos gestionados se asignan a tipos no administrados).
  • Trabajas con C ++ / CLI, lo cual es muy divertido de aprender y está realmente pulido. Ha recorrido un largo camino desde VS 2003 y ahora es un lenguaje .NET con todas las funciones. La documentación de Microsoft es bastante buena, al igual que toda la información de IJW.
  • Hacer la interoperabilidad de C ++ en C ++ / CLI es muy natural en comparación con C #. Esto es completamente subjetivo, pero preferiría hacer una ordenación de cadenas en C ++ que haga Marshal.PtrToString(ptr) .
  • Si expone una API, probablemente desee envolver todos los elementos P / Invocar en otra capa, para que no tenga que lidiar con P / Invocar fealdad. De esta manera usted tiene la sobrecarga de toda la clasificación Y la capa C # alrededor de ella. Con C ++ / CLI, la clasificación y la abstracción de interoperabilidad están en un solo lugar, y puede elegir la cantidad de coordinación que necesita.

En mi humilde opinión, si está llamando a una función extraña en Windows SDK, vaya con P / Invoke. Si está exponiendo una API de C ++ moderadamente compleja al mundo administrado, definitivamente C ++ / CLI.