Eine COM-Bridge zum Aufruf einer 64-Bit-DLL aus einer 32-Bit-Anwendung – ein Praxisbeispiel
· Go Komura · COM, Windows-Entwicklung, 32bit, 64bit
Die Anforderung, eine 64-Bit-DLL aus einer 32-Bit-Anwendung heraus aufzurufen, ist unter Windows recht typisch. Vor allem wenn vorhandene Bestände erhalten bleiben sollen und nur die Funktionalität der 64-Bit-Seite genutzt werden soll, erweist sich eine COM-Bridge-Architektur häufig als praktikable Lösung.
Zielgruppe: Wer eine bestehende 32-Bit-Windows-Anwendung pflegt und DLLs oder Bibliotheken auf der 64-Bit-Seite nutzen möchte. Der Text ist so geschrieben, dass er auch mit dem Vorwissen „von COM schon gehört, aber selbst noch nichts damit gebaut“ lesbar ist.
Vorausgesetzte Umgebung: Eine 64-Bit-Version von Windows (x64) sowie eine Entwicklungsumgebung, in der Sie C# schreiben können (etwa Visual Studio). Für die Registrierung eines COM-Servers systemweit (unter HKEY_LOCAL_MACHINE) sind Administratorrechte erforderlich. Die grundlegende Denkweise von COM ordnen wir in „Was ist COM? – Warum das Design von Windows COM auch heute noch schön ist“ ein.
Inhaltsverzeichnis
- Die Ausgangslage
- Die Lösung
- Der Ablauf (Sequenzdiagramm)
- Beispielcode (konzeptionell)
- Vollständiger Beispielcode
- Zusammenfassung
- Quellen
1. Die Ausgangslage
Das ist der Fall, in dem die bestehende 32-Bit-Anwendung unverändert bleiben soll, aber die Verarbeitung einer 64-Bit-DLL genutzt werden soll. Das Problem: Ein 32-Bit-Prozess kann keine 64-Bit-DLL laden. Das ist eine Einschränkung auf Betriebssystemebene – kein Problem, das sich mit einem Kunstgriff lösen ließe.
Häufig sieht die Situation so aus:
- Die bestehende 32-Bit-Anwendung ist ein großer Bestand und lässt sich nicht kurzfristig migrieren
- Die 64-Bit-DLL bringt neue Funktionen mit, oder ihre Abhängigkeiten liegen nur in 64-Bit vor
- Der Aufruf von der 32-Bit-Seite soll „typsicher“ erfolgen
Bei dieser Kombination ist der Weg über denselben Prozess von vornherein versperrt.
2. Die Lösung
Da ab diesem Kapitel Fachbegriffe folgen, hier zunächst das nötige Minimum an Vokabular.
| Begriff | Bedeutung |
|---|---|
| In-Proc-COM (DLL-Server) | Eine COM-Komponente wird in denselben Prozess wie der Aufrufer geladen und genutzt. Schnell, lässt sich aber bei unterschiedlicher Bitness nicht laden |
| Out-of-Proc-COM (EXE-Server) | Eine COM-Komponente wird als separater Prozess gestartet und genutzt. Funktioniert auch bei unterschiedlicher Bitness |
| LocalServer | Ein COM-Server, der als separater Prozess auf demselben Rechner läuft. Der Pfad zur EXE wird im Registrierungsschlüssel LocalServer32 hinterlegt |
| IDL / TypeLib | Die Definition der Schnittstellenform (Methodennamen, Parametertypen) als IDL sowie deren binäre Form als TypeLib. Beide Seiten nutzen so denselben „Vertrag“ |
| Marshalling | Das Umpacken von Argumenten und Rückgabewerten in eine übertragbare Form, um die Prozessgrenze zu überschreiten. Das Gegenteil ist Unmarshalling |
| Proxy / Stub | Der Stellvertretercode, der das Marshalling tatsächlich durchführt. Auf der Aufruferseite steht der Proxy, auf der Serverseite der Stub |
| WOW6432Node | Der Ort, an dem auf einem 64-Bit-Windows die Registrierungsinhalte für 32-Bit-Anwendungen physisch abgelegt werden. Unter demselben Schlüsselnamen unterscheiden sich die Inhalte auf der 32-Bit- und der 64-Bit-Seite |
Die grundlegende Lösung ist die Trennung über Out-of-Proc-COM (einen EXE-Server). Die 64-Bit-DLL wird von einem 64-Bit-COM-Server (EXE) aus aufgerufen, und die 32-Bit-Anwendung nutzt ihn über COM.
Der Ablauf sieht so aus:
- Einen 64-Bit-COM-LocalServer (EXE) bereitstellen, der intern die 64-Bit-DLL aufruft
- Die COM-Schnittstelle (IDL/TypeLib) teilen, um die Typen offenzulegen
- Die 32-Bit-Anwendung ruft COM „typsicher“ auf (Kommunikation über Proxy/Marshalling)
Es gibt jedoch auch Dinge zu beachten.
- Die Registrierung für 32-Bit und 64-Bit ist getrennt (einschließlich WOW6432Node)
- Eigene Strukturen erfordern ein Marshalling-Design
- IPC-Overhead – bei häufigen Aufrufen ist Vorsicht geboten
Mit anderen Worten: Der Königsweg lautet, „die 64-Bit-Verarbeitung in einen separaten Prozess auszulagern und über COM zu überbrücken.“
3. Der Ablauf (Sequenzdiagramm)
Im Folgenden der Ablauf, wenn die 32-Bit-Anwendung die Verarbeitung der 64-Bit-DLL aufruft.
sequenceDiagram
participant App as 32-Bit-Client-App
box rgba(100,100,255,0.1) Wird von der registrierten COM-Marshalling-Infrastruktur verarbeitet
participant Proxy as COM-Proxy<br/>(32-Bit-Seite)
participant RPC as RPC/IPC<br/>(Interprozesskommunikation)
participant Stub as COM-Stub<br/>(64-Bit-Seite)
end
participant Server as 64-Bit-COM-Server<br/>(EXE)
participant DLL as 64-Bit-DLL
App->>Proxy: ICalcService.Add(1, 2)
rect rgba(100,100,255,0.1)
Note over Proxy: Parameter marshallen
Proxy->>RPC: Serialisierte Daten
RPC->>Stub: Über die Prozessgrenze übertragen
Note over Stub: Parameter unmarshallen
end
Stub->>Server: Add(1, 2)
Server->>DLL: Nativer Funktionsaufruf
DLL-->>Server: Ergebnis: 3
Server-->>Stub: Ergebnis: 3
rect rgba(100,100,255,0.1)
Note over Stub: Rückgabewert marshallen
Stub-->>RPC: Serialisiertes Ergebnis
RPC-->>Proxy: Über die Prozessgrenze übertragen
Note over Proxy: Rückgabewert unmarshallen
end
Proxy-->>App: Ergebnis: 3
Wichtig:
- Die 32-Bit-Anwendung kann über die Schnittstelle
ICalcServicetypsicher aufrufen - Die COM-Laufzeit überschreitet die Prozessgrenze mithilfe der registrierten Proxy/Stub-DLL, des TypeLib-Marshallers, des Standard-Marshallers und Ähnlichem
- Wegen des Interprozesskommunikations-Overheads ist Sammelverarbeitung feingranularen Aufrufen vorzuziehen
4. Beispielcode (konzeptionell)
4.1. Gemeinsame Schnittstelle sowie Server und Client
Das Folgende ist eine konzeptionelle Skizze. Damit sie tatsächlich läuft, ist zusätzlich die Registrierung aus 4.2 nötig.
// Gemeinsame Schnittstelle (IDL-Äquivalent)
[ComVisible(true)]
[Guid("7A4B5B23-0A2F-4D2B-9D4D-8A2A92B8B001")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalcService
{
int Add(int a, int b);
}
// 64-Bit-COM-LocalServer (EXE-Seite)
[ComVisible(true)]
[Guid("1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("KomuraSoft.CalcService")]
public class CalcService : ICalcService
{
public int Add(int a, int b)
{
// Hier wird die 64-Bit-DLL aufgerufen
return a + b;
}
}
// 32-Bit-App-Seite (Client)
Type t = Type.GetTypeFromProgID("KomuraSoft.CalcService");
var calc = (ICalcService)Activator.CreateInstance(t);
int result = calc.Add(1, 2);
In dieser Form lässt sich die 32-Bit-Seite „typsicher“ ansprechen. COM setzt intern Proxy/Stub ein und übernimmt den Aufruf über IPC.
[ProgId("KomuraSoft.CalcService")] ist gesetzt, damit die Client-Seite sie über Type.GetTypeFromProgID("KomuraSoft.CalcService") finden kann. Die ProgID ist nur ein „für Menschen lesbarer Alias“ – den Server tatsächlich findet die im Folgenden erläuterte Registrierung der CLSID.
4.2. Die minimal nötigen Registrierungsschritte
COM funktioniert nach dem Prinzip, dass die COM-Laufzeit eine in der Registrierung hinterlegte CLSID nachschlägt und darüber startet. Deshalb läuft nicht registrierter Code grundsätzlich nicht (Type.GetTypeFromProgID liefert null, oder CreateInstance liefert REGDB_E_CLASSNOTREG). Für einen EXE-Server (LocalServer) sind im Kern nur die folgenden drei Schlüssel nötig.
| Was registriert wird | Schlüssel | Wert |
|---|---|---|
| Zuordnung ProgID → CLSID | HKEY_CLASSES_ROOT\KomuraSoft.CalcService\CLSID |
{1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11} |
| Zuordnung CLSID → EXE-Pfad | HKEY_CLASSES_ROOT\CLSID\{1C9B6F4D-…}\LocalServer32 |
Vollständiger Pfad zur 64-Bit-COM-Server-EXE |
| Rückverweis CLSID → ProgID | HKEY_CLASSES_ROOT\CLSID\{1C9B6F4D-…}\ProgID |
KomuraSoft.CalcService |
Hier liegt genau die Falle, die das Kernthema dieses Artikels ist. HKEY_LOCAL_MACHINE\SOFTWARE\Classes wird von 32-Bit- und 64-Bit-Anwendungen gemeinsam genutzt, aber die darunterliegenden CLSID-Unterschlüssel (und ebenso Interface und Ähnliches) sind für die 32-Bit- und die 64-Bit-Seite getrennt (die 32-Bit-Ausprägung liegt physisch unter WOW6432Node) – das steht ausdrücklich in der Microsoft-Dokumentation. Der ProgID-Schlüssel muss also nur einmal geschrieben werden, um von beiden Seiten sichtbar zu sein, aber die Registrierung der CLSID muss sowohl in die 32-Bit- als auch in die 64-Bit-Ansicht geschrieben werden, sonst findet der 32-Bit-Client den Server nicht.
In einer Eingabeaufforderung mit Administratorrechten ist es zuverlässig, den reg-Befehl mit /reg:32 und /reg:64 zu verwenden (den Wow6432Node-Anteil selbst in den Pfad zu schreiben, rät Microsoft ausdrücklich ab).
:: In einer Eingabeaufforderung mit Administratorrechten ausführen
set CLSID={1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11}
set PROGID=KomuraSoft.CalcService
set SERVER=C:\Program Files\KomuraSoft\CalcServer.exe
:: 1) ProgID -> CLSID (direkt unter HKLM\SOFTWARE\Classes wird von 32/64 gemeinsam genutzt)
reg add "HKLM\SOFTWARE\Classes\%PROGID%\CLSID" /ve /d "%CLSID%" /f
:: 2) CLSID -> LocalServer32 und ProgID (unter CLSID ist es für 32/64 getrennt, daher in beide schreiben)
:: In den Wert von LocalServer32 den Pfad zur ausführbaren Datei samt Anführungszeichen eintragen.
:: Schreibt man /d "%SERVER%", werden die Anführungszeichen bei der Argument-Analyse von
:: reg.exe entfernt, und der Wert wird als C:\Program Files\... ohne Anführungszeichen
:: gespeichert. COM interpretiert dies als Kommandozeile und sucht daher zuerst nach
:: C:\Program.exe, dem Teil vor dem Leerzeichen
reg add "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\LocalServer32" /ve /d "\"%SERVER%\"" /f /reg:64
reg add "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\ProgID" /ve /d "%PROGID%" /f /reg:64
reg add "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\LocalServer32" /ve /d "\"%SERVER%\"" /f /reg:32
reg add "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\ProgID" /ve /d "%PROGID%" /f /reg:32
:: Den gespeicherten Wert prüfen. Erscheint er als "C:\Program Files\..." mit Anführungszeichen, ist es korrekt
reg query "HKLM\SOFTWARE\Classes\CLSID\%CLSID%\LocalServer32" /ve /reg:64
Die Anführungszeichen bei LocalServer32 sind nicht bloß eine Stilfrage. Fehlen sie, lässt sich C:\Program Files\... auch so deuten, dass „C:\Program mit dem Argument Files\... aufgerufen wird“. Das Ergebnis: In einer Umgebung, in der eine Gegenpartei die Berechtigung hat, C:\Program.exe anzulegen, kann genau diese Datei zuerst gestartet werden. Bei Pfaden mit Leerzeichen sind Anführungszeichen deshalb unbedingt zu setzen.
Das Entfernen erfolgt einfach durch Löschen derselben Schlüssel.
set CLSID={1C9B6F4D-1E9A-4E61-9A4F-6A0F1D2D9A11}
set PROGID=KomuraSoft.CalcService
reg delete "HKLM\SOFTWARE\Classes\CLSID\%CLSID%" /f /reg:64
reg delete "HKLM\SOFTWARE\Classes\CLSID\%CLSID%" /f /reg:32
reg delete "HKLM\SOFTWARE\Classes\%PROGID%" /f
Zusätzlich muss sich die EXE beim Start bei COM als „zuständig für diese CLSID“ melden. In C/C++ übernimmt das CoRegisterClassObject, im .NET Framework RegistrationServices.RegisterTypeForComClients. Die Registrierung in der Registry kümmert sich nur darum, dass COM die EXE startet – fehlt diese Meldung, entsteht der schwer zu durchschauende Fehler, dass die EXE zwar startet, sich aber kein Objekt erzeugen lässt.
Zum Ausprobieren während der Entwicklung genügt es übrigens, statt in HKLM mit derselben Struktur unter HKCU\SOFTWARE\Classes zu schreiben – dann ist keine Administratorberechtigung nötig (HKEY_CLASSES_ROOT ist eine Zusammenführung von HKLM und HKCU). Allerdings ist auch HKCU\SOFTWARE\Classes\CLSID für 32-Bit/64-Bit getrennt, sodass sich daran nichts ändert: Es muss weiterhin in beide Ansichten geschrieben werden.
4.3. .NET Framework und .NET (5 und neuer) unterscheiden sich im Vorgehen
Der obige Code ist C#, aber je nachdem, welches .NET Sie verwenden, unterscheidet sich das Vorgehen erheblich. Wer das vermischt, gerät ins Stocken.
| .NET Framework | .NET (Core 3.0 / 5 und neuer) | |
|---|---|---|
| Registrierungswerkzeug | RegAsm.exe ist vorhanden (erzeugt wird jedoch die für In-Proc gedachte InprocServer32-Registrierung, LocalServer32 muss also ohnehin selbst geschrieben werden) |
Ein zu RegAsm gleichwertiges Werkzeug gibt es nicht |
| Standardmäßige COM-Offenlegung | Attribute an der Assembly plus RegAsm |
<EnableComHosting>true</EnableComHosting> erzeugt *.comhost.dll, registriert mit regsvr32 (nur In-Proc) |
| Erzeugung der TypeLib (.tlb) | Erzeugbar mit TlbExp / RegAsm /tlb |
Nicht unterstützt. Die IDL wird von Hand geschrieben und mit MIDL kompiliert (ab .NET 6 lässt sich die fertige .tlb in den Comhost einbetten) |
| Angabe der CLSID | Optional | Für Klassen, die von COM erzeugt werden sollen, ist eine explizite CLSID zwingend |
| Umgang mit AnyCPU | Von 32-Bit- und 64-Bit-Clients aus nutzbar | Die zugehörige *.comhost.dll ist standardmäßig 64-Bit, deshalb nur von 64-Bit-Clients aus nutzbar |
Der in diesem Artikel beschriebene Aufbau (EXE-Server) liegt unter .NET (5 und neuer) außerhalb dessen, was das Standard-EnableComHosting abdeckt – die Registrierungslogik muss also selbst geschrieben werden. Als offizielles Microsoft-Beispiel steht OutOfProcCOM zur Verfügung; wer auf .NET-Seite aufbaut, findet dort den Ausgangspunkt.
5. Vollständiger Beispielcode
Ein tatsächlich lauffähiges Beispiel, das die oben beschriebenen Konzepte umsetzt, ist auf GitHub veröffentlicht.
Call64bitDLLFrom32bitProc – GitHub
Das Repository enthält Folgendes:
- Call64bitDLLFrom32bitProc/ – 64-Bit-COM-LocalServer (EXE)
- X64DLL/ – 64-Bit-DLL (die eigentliche Verarbeitung)
- X86App/ – 32-Bit-Client (WinForms)
- scripts/ – Skripte zum Registrieren und Deregistrieren des COM-Servers
Folgt man den Schritten im README für Build und Registrierung, lässt sich tatsächlich beobachten, wie ein 32-Bit-Prozess eine 64-Bit-DLL aufruft.
6. Zusammenfassung
Eine COM-Bridge ist kein Allheilmittel – es zeigt sich klar, für welche Aufgaben sie geeignet ist und für welche nicht. Bevor Sie sich dafür entscheiden, ordnen Sie Ihren Fall anhand der folgenden Tabelle ein.
| Geeignete Fälle | Ungeeignete Fälle |
|---|---|
| Die 32-Bit-Anwendung selbst lässt sich nicht neu bauen (der Umbauaufwand lohnt sich nicht) | Die 32-Bit-Seite lässt sich ohnehin auf 64-Bit neu kompilieren (das ist der kürzeste Weg) |
| Die Aufrufe sind grobkörnig (z. B. ein Bild oder eine Datei pro Aufruf) | Zehntausende feingranulare Aufrufe mit hoher Frequenz, etwa Element für Element (der IPC-Overhead dominiert dann) |
| Ausgetauscht werden Zahlen, Zeichenketten, Arrays und Ähnliches, die sich leicht marshallen lassen | Rohe Zeiger oder komplexe eigene Strukturen werden massenhaft hin- und hergeschickt |
| Auch wenn die 64-Bit-Seite abstürzt, soll die Hauptanwendung weiterlaufen (die Prozesstrennung ist hier ein Vorteil) | Sie wollen keine Wiederherstellungslogik für Abstürze oder Neustarts der Serverseite schreiben |
| Der typsichere Aufruf (IntelliSense, Prüfung zur Kompilierzeit) soll erhalten bleiben | Eine einmalige Stapelverarbeitung genügt, und der Austausch über Standard-E/A oder Dateien reicht aus |
Als Kehrseite der letzten Zeile lohnt sich auch immer die schlichte Alternative, „die 64-Bit-Verarbeitung als reine Konsolen-EXE auszuführen und über Argumente und Dateien auszutauschen“. Eine COM-Bridge lohnt sich, wenn der typsichere Aufruf erhalten bleiben soll oder wenn ein zustandsbehafteter Server mehrfach aufgerufen werden soll.
Als nächste Schritte empfehlen wir diese Reihenfolge:
- Zunächst das Beispiel-Repository aus Kapitel 5 klonen, gemäß README bauen und registrieren, und so einen lauffähigen Zustand vor Ort herstellen.
- Eine einzige Funktion Ihrer eigenen 64-Bit-DLL auswählen und der zu
ICalcServiceanalogen Schnittstelle eine passende Methode hinzufügen, um sie durchzuspielen. - Sobald das funktioniert, die Zahl der Aufrufe und die Datenmenge pro Aufruf messen. Trifft man die Entscheidung, sich auf grobkörnige Aufrufe zuzubewegen (mehrere Aufrufe zu einem zusammenzufassen), an dieser Stelle vorab, verringert das spätere Nacharbeit.
7. Quellen
- Überblick über das Component Object Model (COM) https://learn.microsoft.com/en-us/windows/win32/com/component-object-model–com–portal
- Registrierung von COM-LocalServer32 https://learn.microsoft.com/en-us/windows/win32/com/localserver32
- Grundlagen der COM-Schnittstelle https://learn.microsoft.com/en-us/windows/win32/com/the-component-object-model
- COM-Interop (Nutzung aus .NET) https://learn.microsoft.com/en-us/dotnet/standard/native-interop/cominterop
- WOW64-Registrierungsumleitung (
HKLM\SOFTWARE\Classeswird gemeinsam genutzt, der Bereich unterCLSIDist für 32/64 getrennt) https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys - Komponenten aus .NET (Core / 5 und neuer) gegenüber COM offenlegen https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
Verwandte Artikel
Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.
Registrierungs- und Bitness-Fallen bei der COM/OCX/ActiveX-Entwicklung
Wir ordnen die typischen Fallen der COM-, OCX- und ActiveX-Entwicklung – 32bit/64bit, Visual Studio 2022, regsvr32/Regasm, Administratorr...
Warum ActiveX in Office 2024/Microsoft 365 nicht mehr funktioniert – und wie Sie es diagnostizieren
Wenn ActiveX in Office 2024/Microsoft 365 nicht funktioniert: die richtige Reihenfolge, um Standarddeaktivierung, 32-Bit/64-Bit, COM-Regi...
Laufen Business-Anwendungen unter Windows on Arm? ── Die Realität von x64-Emulation (Prism) und nativen DLLs/COM
Eine Antwort für Entwicklerinnen, Entwickler und IT-Verantwortliche auf die Frage „Läuft unsere Business-Anwendung unter Windows on Arm?“...
Windows-App-Outsourcing und Auftragsentwicklung: Was Sie vor der Beauftragung klären sollten
Bevor Sie die Entwicklung einer Windows-App outsourcen oder in Auftrag geben, sollten Sie folgende Punkte klären: Überarbeitung bestehend...
Die seltsame Liebe eines Entwicklers, oder: Wie ich lernte, mir keine Sorgen mehr zu machen, und Windows lieben lernte
Windows ist umständlich. Aber diese Umständlichkeit ist auch die Umständlichkeit eines Betriebssystems, das jahrzehntelang reale Geschäft...
Verwandte Themen
Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.
Technische Windows-Themen
Portal zu Windows-Entwicklung, Fehleranalyse und der Nutzung bestehender Assets.
ActiveX-Migration
Entscheidungen zum Beibehalten, Kapseln oder Ersetzen von COM / ActiveX / OCX.
32-/64-Bit-Interoperabilität
32-/64-Bit-Kompatibilität, native Grenzen und Windows-Entscheidungen.
Leistungen zu diesem Thema
Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.
Nutzung und Migration bestehender Assets
Es geht darum, eine Brücke zur 64-Bit-Seite zu schlagen und dabei vorhandene 32-Bit-Bestände zu erhalten – das steht in direktem Zusammenhang mit der Nutzung und Migration vorhandener Ressourcen.
Technische Beratung und Design-Review
Wenn Sie zunächst den Entwurf der COM-Bridge oder die Aufteilung der Prozessgrenzen klären wollen, lässt sich das als technische Beratung mit Design-Review vergleichend durchdenken.
Häufige Fragen
Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.
- Kann eine 32-Bit-Anwendung eine 64-Bit-DLL direkt aufrufen?
- Nein. Ein 32-Bit-Prozess kann keine 64-Bit-DLL laden – das ist eine Einschränkung auf Betriebssystemebene, die sich nicht mit einem Kunstgriff umgehen lässt. Der Weg über den gleichen Prozess ist von vornherein versperrt, sodass die Verarbeitung auf der 64-Bit-Seite in einen separaten Prozess ausgelagert werden muss.
- Wie nutzt man die Funktionen einer 64-Bit-DLL aus einer 32-Bit-Anwendung heraus?
- Der Königsweg ist die Trennung über Out-of-Proc-COM (einen EXE-Server). Die 64-Bit-DLL wird von einem 64-Bit-COM-LocalServer (einer EXE) aus aufgerufen, und die 32-Bit-Anwendung nutzt ihn typsicher über eine COM-Schnittstelle. Die COM-Schnittstelle (IDL/TypeLib) wird geteilt, um die Typen offenzulegen, und die COM-Laufzeit überbrückt die Prozessgrenze mit Proxy/Stub und Interprozesskommunikation.
- Worauf muss man bei einer COM-Bridge-Architektur achten?
- Es gibt vor allem drei Punkte. Erstens sind die Registrierungen für 32-Bit und 64-Bit getrennt (einschließlich WOW6432Node). Zweitens erfordern eigene Strukturen ein durchdachtes Marshalling-Design. Drittens entsteht durch die Interprozesskommunikation ein Overhead, weshalb bei häufigen, feingranularen Aufrufen Vorsicht geboten ist – es ist besser, auf Sammelverarbeitung statt auf viele einzelne Aufrufe zu setzen.
- Gibt es tatsächlich lauffähigen Beispielcode?
- Ja. Im GitHub-Repository Call64bitDLLFrom32bitProc ist ein vollständiges Beispiel veröffentlicht, das einen 64-Bit-COM-LocalServer (EXE), eine 64-Bit-DLL, einen 32-Bit-Client (WinForms) sowie Skripte zum Registrieren und Deregistrieren des COM-Servers enthält. Folgt man den Schritten im README für Build und Registrierung, lässt sich beobachten, wie ein 32-Bit-Prozess tatsächlich eine 64-Bit-DLL aufruft.
Autorenprofil
Profilseite des Artikelautors.
Go Komura
Geschäftsführer von KomuraSoft LLC
Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.