2010-03-28 34 views
23

¿Es una buena idea combinar C++ y C# o plantea algún problema inmediato?Combinando C++ y C#

Tengo una aplicación que necesita algunas partes para ser C++, y algunas partes para ser C# (para mayor eficiencia). ¿Cuál sería la mejor manera de lograr el uso de un dll nativo de C++ en C#?

Respuesta

25

Sí, usar C# y C++ para su producto es muy común y una buena idea.

A veces puede utilizar C++ administrado, en cuyo caso puede usar su módulo C++ administrado como cualquier otro módulo .NET.

Normalmente haría todo lo que pueda en C#. Para las partes que necesita hacer en C++, normalmente crearía una DLL C++ y luego llamaría a esa DLL desde C#. La clasificación de los parámetros se realiza automáticamente para usted.

Aquí es un ejemplo de la importación de una función C dentro de una DLL en C#:

[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)] 
internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount); 
+0

¿Es eso publicidad para .NET? ¿Qué pasa con la compatibilidad multiplataforma, problemas de conexión, curva de aprendizaje, etc.? –

+1

Curva de aprendizaje? Supongo que conoces los conceptos básicos de C++ y C# cuando intentas combinar idiomas. ¿Plataforma cruzada? Es obvio que escribir código multiplataforma en C++ es mucho más difícil, pero posible. Parece incluso un poco más fácil cuando se combina con C#: un código de nivel superior puede decidir qué partes de C/C++ se cargarán y usarán en una plataforma específica. – Harry

+0

@Harry: Aceptaré tu respuesta cuando me muestres (por ejemplo) C# trabajando en un PIC ;-) –

29

La pregunta es claramente la forma de integrar su propio código C++ para su solución C#, no sólo lo atribuyen a utilizar con el fin para llamar a una función existente desde la API win32. Incluso si la respuesta ya fue aceptada, creo que está incompleta, y lo siguiente debe aplicarse.

Sí, es una práctica común en los casos en que la tarea puede ejecutarse más rápido, utilizar menos recursos y, en algunos casos, acceder a métodos que no están disponibles en .NET Framework.

Si su objetivo es ganar eficiencia que necesita para codificar un C no administrado nativo ++ biblioteca, se crea un nuevo proyecto no administrado C++ (que recoge como una biblioteca DLL) en el estudio visual y referencia de esta biblioteca de su proyecto de C# .

En su caso, parece que podría estar escribiendo una biblioteca C++ no administrada, y se aplica lo siguiente.

En cuanto a cualquier problema inmediato que haya preguntado sobre, afectaría el despliegue y la ofuscación.

  • Despliegue: Tenga en cuenta que los # archivos DLL C a construir se pueden ejecutar en cualquier CPU, 32 y 64 bits, pero esta nueva C nativa y no administrado ++ biblioteca forzar su programa para estar a favor 32 o 64 específico.

    Esto es algo que va a configurar en el administrador de configuración de Visual Studio, y serán atendidos en tiempo de compilación tiempo, que recogerá Cualquier CPU para C# asambleas y para su nuevo C++ no administrado biblioteca, que estará en es su propio proyecto, tendrá para elegir entre win32 o x64.

    por lo que ahora tiene 2 configuraciones, es las mejores prácticas recomendadas para tener configuraciones separadas, una para 32 y otra para 64. O desde 32 bits apoyo está cayendo muy rápido, podría centrarse en 64 bits solamente.

    Además, su biblioteca podría terminar haciendo referencia al VC++ redistribuible proporcionado por Visual Studio, que podría tener que incluir en su implementación, aunque algunas versiones están incluidas en muchos sistemas operativos, encontré que raramente es el mismo que compilé con y es mejor implementarlo con su aplicación para estar seguro. Si falta este paquete, la máquina objetivo tendrá una excepción SideBySide en el eventviewer-> log de la aplicación.

    Para capturar y manejar una excepción lanzada desde un código no administrado, el único truco que funciona es el vacío, el que no tiene una excepción en el paréntesis después del catch(). Para que pueda envolver sus llamadas al código no administrado en esto para manejar todas las excepciones no administradas lanzadas desde el interior del código no administrado, si coloca un tipo .net como catch (Exception), simplemente lo saltará. La única forma de atrapar una excepción no administrada, dentro del código administrado, es en este formato.


    try 
    { 
     //call unmanaged code 
    } 
    catch 
    { 
     //handle unmanaged exception 
    } 

  • ofuscación: Cualquier llamada de método realizadas desde C# que ahora califican código no administrado ahora serán excluidos de cambio de nombre automáticamente. Y por el otro lado, si su no administrado biblioteca de C++ necesita para llamar a métodos de sus ensamblados administrados, los tendrá que ser excluidos de cambio de nombre, de forma manual, con el fin de ser visible para la biblioteca C++ llamar ellos.

Si lo que necesita es sólo para llamar a C bibliotecas bien conocidos ++ como los de Windows, no será necesario crear un nuevo proyecto no administrado C++, sólo utilizan la [DllImport()] atributo sugirió en una respuesta anterior. Y en este caso se podría echar un vistazo a esta referencia http://www.pinvoke.net/

+0

* 'captura y maneja una excepción lanzada desde un código no administrado' * - Creo que esto tiene que ser reformulado, capturar sin excepción la especificación de tipo solo significa capturar excepciones. No hay una manera fácil para un manejo específico, pero la captura mantiene en funcionamiento su aplicación C# ... Vea también [.net - ¿Puede capturar una excepción nativa en el código C#? - Desbordamiento de pila] (https://stackoverflow.com/questions/150544/can-you-catch-a-native-exception-in-c-sharp-code) y [CA2102: Captura excepciones que no cumplen CLS en controladores generales] (https://msdn.microsoft.com/en-gb/bb264489.aspx) – Wolf

-2

información adicional sobre C# diferencias frente a C++ y POSSIBLES cuestiones fusionarlos:

  • C# es una interpretarse, como Java. C++ se compila en binario nativo. Eso lleva varias diferencias explicadas más adelante en los siguientes puntos.
  • Compatibilidad de plataforma: C#, como se interpreta y un producto de Microsoft, funciona bien en Windows, correctamente en Linux gracias a un gran proyecto Mono, pero no tan bien (o nada) en otras plataformas (Android, IOS, otros .) Si desea escribir software para incrustado donde no hay soporte de un sistema operativo, o para escribir un sistema operativo en sí mismo, en su mayoría "no se puede" usar C#. C++ es totalmente multiplataforma tan pronto como tenga un compilador (que generalmente es el caso).
  • El código interpretado suele ser un orden de magnitud más lento que el código binario [1]. Por eso usarás C++ vinculado.
  • Código binario vs intermedio: trabajo de código intermedio en cualquier intérprete disponible en una arquitectura específica, C++ requiere recompilar para cada arquitectura.
  • Curva de aprendizaje: los desarrolladores deben aprender varios idiomas, lo que aumenta el tiempo de aprendizaje. También es más difícil encontrar expertos en ambos idiomas.
  • IDE: Para C++, cualquier editor de texto es suficiente, para C# requerirá principalmente un IDE específico.
  • Tiempo real: parece difícil imaginar las condiciones en tiempo real con C#.
  • Algunas certificaciones de calidad podrían ser imposibles de obtener con el código C# (software crítico).

¿Es una buena idea combinarlos?

Eso probablemente dependa de su proyecto. Para un gran desarrollo de HMI en Windows, es probable que mejore su tiempo de desarrollo. Pero, otros requisitos de software podrían restringirte a C++ únicamente.


[1] He leído muchas veces que interpreta el código es en algunos casos incluso más rápido que el código binario, esto se debe a un error: El intérprete implementa varias funciones para la comodidad, por lo que cuando se llama a (por ejemplo) sort(), en realidad llama a una implementación binaria de esta función. Si esta función está bien optimizada, el tiempo final podría ser más rápido, pero solo porque todos se ejecutan en binario y el componente interpretado es mínimo en comparación con todo el tiempo requerido para ordenar. Por otro lado, si codifica una lógica completa en ambos idiomas, la versión binaria siempre será significativamente más rápida. La razón es simple: un intérprete ES un binario que ejecuta, además de su código, todo el marco de lenguaje.

+1

Jit no es lo mismo que se interpreta. Jit puede compilar a código de máquina. – tohava

+0

Incluso con C# "totalmente compilado", que no es el caso común, la mayoría de las afirmaciones aquí siguen siendo válidas. Solo que no se interpreta y la diferencia entre el rendimiento no es tan grande. –