2009-12-01 8 views
8

Quali sono le opzioni quando si tratta di utilizzare una DLL .NET da un processo Win32? Ho bisogno di usare fondamentalmente un C# DLL da un processo Win32.Come chiamare una DLL .NET da un processo Win32?

Ho una soluzione possibile in questo momento che richiede l'aggiunta della DLL C# al GAC (utilizzando RegAsm.exe), quindi chiama la DLL C# tramite le chiamate COM avvolte. Tuttavia, questa soluzione è piuttosto pesante. Si richiede che la DLL .NET essere aggiunto alla GAC su tutte le macchine che dovrebbero eseguire questo processo Win32.

Sarebbe possibile farlo senza dover chiamare RegAsm prima di poter utilizzare la DLL C#?

+0

Non deve essere nel GAC con l'opzione Regasm.exe/codebase. –

risposta

11

È possibile utilizzare COM senza registrazione con componenti COM .NET - vedere here.

Un'altra opzione è utilizzare C++/CLI come bridge. La maggior parte delle persone ha familiarità con l'uso di wrapping API non gestite per esporre a codice gestito, ma funziona in entrambi i modi: è possibile compilare con /clr e produrre un assembly .dll con esportazioni non gestite semplici, che possono essere chiamate da codice non gestito come di solito. Ecco un esempio molto semplice che espone System::String::ToUpper in questo modo:

// compile with cl.exe /clr /LD wrapper.cpp ole32.lib 

#include <windows.h> 

__declspec(dllexport) 
wchar_t* ToUpper(const wchar_t* wcs) 
{ 
    System::String^ s = gcnew System::String(wcs); 
    array<wchar_t>^ chars = s->ToUpper()->ToCharArray(); 

    size_t size = chars->Length * 2; 
    wchar_t* dst = (wchar_t*)CoTaskMemAlloc(size + 2); 
    pin_ptr<wchar_t> src = &chars[0]; 
    memcpy(dst, src, size); 
    dst[chars->Length] = 0; 
    return dst; 
} 

Questo produrrà wrapper.dll - ibrido riuscito/non gestito di montaggio - e una libreria di esportazione wrapper.lib. Quest'ultimo può essere utilizzato in un'applicazione nativa pura come segue:

// compile with cl.exe test.cpp ole32.lib wrapper.lib 
// note, no /clr 

#include <stdio.h> 
#include <windows.h> 

wchar_t* ToUpper(const wchar_t* wcs); 

int main() 
{ 
    wchar_t* s = ToUpper(L"foo"); 
    wprintf(L"%s", s); 
    CoTaskMemFree(s); 
} 

In pratica si caricherà runtime CLR nel processo chiamante (se non è già caricato lì) e la spedizione dal codice nativo al codice gestito in modo trasparente - tutte le la magia viene eseguita dal compilatore C++/CLI.

+0

Questo suona molto bene, grazie mille. Esplorerò questa soluzione –

+0

* 'here' * punta a [Configurazione di componenti basati su .NET per l'attivazione senza registrazione] (https://msdn.microsoft.com/en-us/library/eew13bza (VS.71) aspx) ... nel caso in cui MS decide di (ri) spostare questo ... le API di hosting – Wolf

7

ci sono due opzioni.

Innanzitutto, è possibile utilizzare Registration Free COM Interop.

In secondo luogo, è possibile utilizzare lo CLR Hosting APIs per ospitare direttamente il CLR e caricare l'assieme. Funziona senza COM.

+1

CLR possono essere utilizzati indirettamente sfruttando C++/CLI - vedi l'aggiornamento per la mia risposta. –