2009-04-24 13 views
9

Me gustaría cargar dinámicamente y utilizar un conjunto .Net creado en C# desde una aplicación Delphi Win32. Mis clases e interfaces están marcadas como ComVisible, pero me gustaría evitar registrar el ensamblado. ¿Esto es posible?¿Cómo usar el ensamblado .Net de Win32 sin registro?

P.S. He encontrado aquí link text otra buena discusión sobre el tema, pero se trata más de alojar el CLR. Lo cual genera una pregunta: ¿por qué alojar CLR versus usar ClrCreateManagedInstance?

+0

Al alojar el CLR a obtener el control de los ganchos de gestión de la memoria y de manejo de excepciones que se crearon para permitir cosas como IIS y SQL Server para controlar muchos aspectos de cómo funciona CLR. – dthorpe

+0

@dthorpe También parece que el alojamiento CLR es la única opción si desea usar .Net4. ¿Sabes si tiene más sobrecarga frente a ClrCreateManagedInstance o instanciación de COM registrada? –

+0

Creo que la sobrecarga sería la misma. En los tres casos, el CLR debe cargarse en el proceso. La única diferencia es quién/cómo se inicia la carga. – dthorpe

Respuesta

8

Por extraño que parezca, no pude encontrar una respuesta en StackOverflow, y no hay mucho en la red, especialmente para Delphi. Encontré la solución de ejemplos publicados here. Aquí es lo que tengo al final:

function ClrCreateManagedInstance(pTypeName: PWideChar; const riid: TIID; 
out ppObject): HRESULT; stdcall; external 'mscoree.dll'; 

procedure TMyDotNetInterop.InitDotNetAssemblyLibrary; 
var 
    MyIntf: IMyIntf; 
hr: HRESULT; 
NetClassName: WideString; 
begin 
//Partial assembly name works but full assembly name is preffered. 
    NetClassName := 'MyCompany.MyDLLName.MyClassThatImplementsIMyIntf, 
      MyCompany.MyDLLName'; 
    hr := ClrCreateManagedInstance(PWideChar(NetClassName), IMyIntf, MyIntf); 
    //Check for error. Possible exception is EOleException with ErrorCode 
    //FUSION_E_INVALID_NAME = $80131047 2148732999 : The given assembly name 
    //or codebase was invalid. 
    //COR_E_TYPELOAD = $80131522 - "Could not find or load a specific type 
    //(class, enum, etc)" 
    //E_NOINTERFACE = $80004002 - "Interface not supported". 
    OleCheck(hr); 
end; 

Por cierto, dependiendo de la situación, es posible que desee cargar Mscoree.dll dinámicamente, ya que podría no estar presentes en el sistema (XP sin .Net Framework)

EDITAR: Lamentablemente, esto fue obsoleto y dejó de funcionar con .Net4 como acabo de descubrir. Esto deja solo dos opciones: CLR hosting and unmanaged export. Además, debugging of .Net4 COM code is broken.

+2

Tenga en cuenta que a menos que ya haya cargado el CLR en su proceso, ClrCreateManagedInstance intentará cargar el v1.0.3705 tiempo de ejecución antes de intentar cargar la última versión ... lo que puede provocar un comportamiento interesante. –

0

Desafortunadamente, esto no se puede hacer (que yo sepa) sin exponer un objeto COM, ya que .NET dll no están realmente compilados en una biblioteca que Delphi (o cualquier otra cosa) puede cargar, ya que todo lo hace el Compilador JIT en tiempo de ejecución.

+0

Pero no necesariamente es necesario registrar clases COM. –

1

Tal vez usando RegFreeCOM y un Com-Envoltura rescatable.

http://msdn.microsoft.com/en-us/magazine/cc188708.aspx

+0

Por lo que tengo entendido, RegFreeCOM es para acceder a COM desde .NET. Mi pregunta era sobre el acceso a COM habilitado .Net desde el código nativo. –

Cuestiones relacionadas