2008-09-19 13 views
25

Supongamos que estoy escribiendo una aplicación en C++ y C#. Quiero escribir las partes de bajo nivel en C++ y escribir la lógica de alto nivel en C#. ¿Cómo puedo cargar un ensamblado .NET desde mi programa C++ y comenzar a llamar a métodos y acceder a las propiedades de mis clases C#?¿Cómo puedo llamar a un ensamblado de .NET desde C/C++?

Respuesta

12
[Guid("123565C4-C5FA-4512-A560-1D47F9FDFA20")] 
public interface IConfig 
{ 
    [DispId(1)] 
    string Destination{ get; } 

    [DispId(2)] 
    void Unserialize(); 

    [DispId(3)] 
    void Serialize(); 
} 

[ComVisible(true)] 
[Guid("12AC8095-BD27-4de8-A30B-991940666927")] 
[ClassInterface(ClassInterfaceType.None)] 
public sealed class Config : IConfig 
{ 
    public Config() 
    { 
    } 

    public string Destination 
    { 
     get { return ""; } 
    } 

    public void Serialize() 
    { 
    } 

    public void Unserialize() 
    { 
    } 
} 

Después de eso, se necesitan Regasm su montaje. Regasm agregará las entradas de registro necesarias para permitir que su componente .NET se vea como un Componente COM. Después, puede llamar a su Componente .NET en C++ de la misma manera que cualquier otro componente COM.

+1

Aquí hay un tutorial, que también muestra la parte de C++: [Cómo llamar a una DLL administrada desde el código nativo de Visual C++ en Visual Studio.NET o en Visual Studio 2005] (http://support.microsoft.com/kb/ 828736) –

+0

Nunca usaría COM para eso. Es muy incómodo y torpe. Exportaría una función en el código C++ y en .NET usaría GetProcAddress() para encontrar este punto de entrada y simplemente llamarlo. Incluso puede implementar devoluciones de llamadas desde código C++ a .NET utilizando un delegado. (https://code.msdn.microsoft.com/windowsapps/Enumerate-top-level-9aa9d7c1) – Elmue

+0

@Elmue Exportación de funciones desde código C++ es si desea llamar al código C++ desde C#, pero la pregunta es cómo llamar C# código de C++. Las devoluciones de llamada no ayudan si el C# DLL aún no está cargado. – BlueMonkMN

0

Puede envolver el componente .NET en un componente COM, que es bastante fácil con las herramientas .NET, y llamarlo a través de COM.

0

Si las partes de nivel bajo entran en C++, entonces normalmente se llama así por el código C# que pasa en los valores que se necesitan. Esto debería funcionar de la manera estándar a la que probablemente estés acostumbrado. Tendrá que leer sobre clasificación, por ejemplo.

Puede consultar este blog para obtener algunos detalles concretos.

0

Crear el ensamblado .NET de forma normal, pero asegúrese de marcar la clase con el ClassInterface (ClassInterfaceType.AutoDual) y asegúrese de que un ensamblaje información SetAssemblyAtribute a ComVisible (verdadero).

A continuación, cree el contenedor COM con Regasm:

regasm mydll.dll /tlb:mydll.tbl/código base f: _code \ ClassLibraryForCom

asegúrese de usar la directiva/código base - es necesario si no le vas a dar un nombre fuerte a la asamblea.

rp

+0

Mason Bendixen advierte contra el uso ClassInterfaceType.AutoDual http://blogs.msdn.com/mbend/archive/2007/04/17/classinterfacetype-none-is-my-recommended-option-over-autodispatch-autodual .aspx – cwick

0

Dado que C# puede importar exportaciones estándar de C++, podría ser más fácil cargar su dll de C++ dentro de una aplicación C# en lugar de usar COM de C++.

Consulte la documentación de System.Runtime.InteropServices.DllImport.

Además, aquí es una lista completa de los tipos de interoperabilidad que se pueden hacer entre el código administrado y no administrado:

http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx

En pocas palabras:

(a) Usando COM-Interop

(b) Uso de las importaciones/PInvoke (llamadas a métodos explícitos)

(c) IJW y MC++ Aplicaciones: MC++ & Las aplicaciones IJW pueden llamar libremente entre sí.

(d) Alojamiento. Esto es raro, pero el CLR puede ser hospedado por una aplicación no administrada, lo que significa que el tiempo de ejecución invoca un conjunto de devoluciones de llamada de hosting.

0

Si puede tener código administrado y no administrado en su proceso, puede crear una clase C++ con funciones virtuales. Implemente la clase con modo mixto C++/CLI. Inyecte la implementación en su código C++, de modo que la implementación (de alto nivel) pueda invocarse desde su código C++ (de bajo nivel).

13

Realmente debería mirar en C++/CLI. Hace que tareas como esta sean casi triviales.

De lo contrario, deberá generar contenedores COM alrededor del código C# y hacer que su aplicación C++ llame a los contenedores COM.

+0

Si usted es un desarrollador de C#, aprender C++/CLI tampoco es realmente tan difícil. Este definitivamente es el camino a seguir. ++ vote –

+0

Parece que eso requeriría refactorizar el código C#? Es ese el caso? – Cenoc

+0

Estoy bastante seguro de que puedes usar código nativo donde sea necesario y luego convertirlo en una biblioteca de clase que puedas usar en cualquier aplicación .net. Sin embargo, podría estar equivocado –

0

He encontrado este enlace para incrustar Mono: http://www.mono-project.com/Embedding_Mono

Proporciona lo que parece ser una interfaz bastante sencilla para interactuar con los conjuntos. Esta podría ser una opción atractiva, especialmente si quiere ser multiplataforma

4

Definitivamente investigaría C++/CLI para esto y evitaría COM y todas las molestias de registro que tiende a producir.

¿Cuál es la motivación para usar C++? Si es simplemente estilo, entonces puede encontrar que puede escribir todo en C++/CLI. Si se trata de rendimiento, la llamada hacia adelante y hacia atrás entre C++ administrado y el código no administrado es relativamente sencillo. Pero nunca va a ser transparente. No puede pasar un puntero administrado a un código no administrado primero sin fijarlo para que el recolector de basura no lo mueva y, por supuesto, el código no administrado no conocerá sus tipos administrados. Pero el código administrado (C++) puede conocer sus tipos no administrados.

Otra cosa que se debe tener en cuenta es que los ensamblados de C++/CLI que incluyen código no administrado serán específicos de la arquitectura. Necesitará construcciones separadas para x86 y x64 (e IA64).

Cuestiones relacionadas