2009-04-24 25 views
9

Mi piacerebbe caricare e utilizzare dinamicamente un assembly .Net creato in C# da un'applicazione Delphi Win32. Le mie classi e interfacce sono contrassegnate come ComVisible, ma vorrei evitare di registrare l'assembly. È possibile?Come utilizzare. Assemblaggio Net da Win32 senza registrazione?

P.S. Ho trovato qui link text un'altra buona discussione sull'argomento, ma è più intorno all'hosting del CLR. Il che fa sorgere una domanda: perché dovresti ospitare CLR rispetto a ClrCreateManagedInstance?

+0

ospitando il CLR a ottenere il controllo di ganci di gestione della memoria e di gestione delle eccezioni che sono stati creati per consentire cose come IIS e SQL Server per controllare molti aspetti di come CLR funziona. – dthorpe

+0

@dthorpe Inoltre, sembra che l'hosting CLR sia l'unica opzione se si desidera utilizzare .Net4. Sai se ha più overhead contro ClrCreateManagedInstance o istanza COM registrata? –

+0

Penso che l'overhead sarebbe lo stesso. In tutti e tre i casi, il CLR deve essere caricato nel processo. L'unica differenza è chi/come viene avviato il caricamento. – dthorpe

risposta

8

Stranamente, non sono riuscito a trovare una risposta su StackOverflow e non c'è molto in Rete, specialmente per Delphi. Ho trovato la soluzione dagli esempi pubblicati here. Ecco quello che ho ottenuto alla fine:

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; 

BTW, a seconda della situazione, si potrebbe desiderare di caricare Mscoree.dll in modo dinamico, perché potrebbe non essere presente nel sistema (XP senza Net Framework)

EDIT: Sfortunatamente, questo è stato deprecato e ha smesso di funzionare con .Net4 come ho appena scoperto. Questo lascia solo due opzioni - CLR hosting and unmanaged export. Inoltre, debugging of .Net4 COM code is broken.

+2

Si noti che, a meno che non sia già stato caricato il CLR nel processo, ClrCreateManagedInstance proverà a caricare il runtime v1.0.3705 prima di provare a caricare l'ultima versione ... il che potrebbe causare un comportamento interessante. –

0

Sfortunatamente questo non può essere fatto (per quanto ne so) senza esporre un oggetto COM, dato che le DLL di .NET non sono VERAMENTE compilate in una libreria che Delphi (o qualsiasi altra cosa) può caricare, dato che è tutto fatto dal Compilatore JIT in fase di esecuzione.

+0

Ma non è necessario registrare le classi COM. –

Problemi correlati