2009-12-01 5 views
8

Welche Optionen gibt es, wenn Sie eine .NET DLL aus einem Win32-Prozess verwenden? Ich muss im Grunde eine C# DLL von einem Win32-Prozess verwenden.Wie ruft man eine .NET DLL von einem Win32 Prozess auf?

Ich habe eine mögliche Lösung im Augenblick, die das Hinzufügen der C# -DLL zum GAC (mit RegAsm.exe) erfordert, dann das Aufrufen der C# -DLL über COM eingehüllte Aufrufe. Allerdings ist diese Lösung ziemlich schwer. Es erfordert, dass die .NET DLL zu dem GAC auf allen Computern hinzugefügt wird, die diesen Win32-Prozess ausführen sollen.

Wäre es möglich, dies zu tun, ohne RegAsm aufrufen zu müssen, bevor die C# -DLL verwendet werden kann?

+0

Es muss nicht in der GAC mit der Option Regasm.exe/codebase sein. –

Antwort

11

Sie können registrierungsfreie COM mit .NET COM-Komponenten verwenden - siehe here.

Eine andere Option ist die Verwendung von C++/CLI als Brücke. Die meisten Leute sind damit vertraut, nicht verwaltete APIs mit verwaltetem Code zu versehen, aber es funktioniert in beide Richtungen - es ist möglich, mit /clr zu kompilieren und dennoch eine .dll Assembly mit einfachen nicht verwalteten Exports zu erzeugen, die aus nicht verwaltetem Code aufgerufen werden können wie gewöhnlich. Hier ist ein sehr einfaches Beispiel, das macht System::String::ToUpper auf diese Weise:

// 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; 
} 

Dies wird produzieren wrapper.dll - Hybrid-Managed/unmanaged Montage - und eine Exportbibliothek wrapper.lib. Letzteres kann in einer reinen nativen Anwendung wie folgt verwendet werden:

// 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 der Praxis wird es CLR Laufzeit in den Anrufprozess geladen werden (es sei denn, es dort bereits geladen wird) und den Versand von nativen Code in verwaltetem Code transparent - alle Magie wird vom C++/CLI-Compiler erledigt.

+0

Das klingt sehr gut, vielen Dank. Ich werde diese Lösung erkunden –

+0

* 'hier' * verweist auf [Konfigurieren von .NET-basierten Komponenten für die Registrierung-Free-Aktivierung] (https://msdn.microsoft.com/en-us/library/eew13bza (VS.71) .aspx) ... für den Fall, dass MS beschließt, das zu verschieben ... – Wolf

7

Es gibt zwei Möglichkeiten.

Zuerst können Sie Registration Free COM Interop verwenden.

Zweitens können Sie die CLR Hosting APIs verwenden, um die CLR direkt zu hosten und die Baugruppe zu laden. Dies funktioniert ohne COM.

+1

CLR-Hosting-APIs können indirekt durch die Nutzung von C++/CLI verwendet werden - siehe das Update zu meiner Antwort. –

Verwandte Themen