2010-12-08 5 views
7

Ich habe ein Problem, dass ich ziemlich sicher bin, dass ich die Antwort weiß, aber ich dachte, ich würde zumindest fragen und sehen, ob es etwas "Magie bullet "das könnte mir große Kopfschmerzen ersparen.Mischen von 32-Bit und 64-Bit P/Invokes

Hier ist die High-Level-Ansicht.

Ich habe eine verwaltete Anwendung. Diese Anwendung verbindet sich mit Hardware über Drittanbieter-Bibliotheken verschiedener Hersteller. Ich habe die volle Kontrolle über die verwaltete App und Null-Kontrolle über die Hardware-API-Bibliotheken.

Hersteller A bietet nur ein natives 32-Bit-SDK. Um es auf 64-Bit-Systemen zu verwenden, haben wir die Anwendung im 32-Bit-Modus ausgeführt. Alles war gut.

Wir integrieren jetzt mit Anbieter B, der 64-Bit-spezifische native API-Bibliotheken auf 64-Bit-Maschinen bereitstellt. Die native 32-Bit-DLL von Hersteller B funktioniert nicht auf einem 64-Bit-System (dies wurde versucht). Wenn ich einen Test-Kabelbaum baue, der als 64-Bit oder AnyCPU läuft, funktioniert es gut. Wenn ich es als 32-Bit markiere, schlägt es bei den P/Invoke-Anrufen fehl.

Es scheint, dass die Hardware von Hersteller A und Hersteller B sich auf 64-Bit-PCs gegenseitig ausschließen wird, aber ich frage mich, ob jemand Vorschläge hat, wie man das möglicherweise umgehen kann.

Antwort

6

Das Problem ist kein .NET oder P/Invoke. Es ist ein Betriebssystemproblem. Ein 64-Bit-Prozess kann nur 64-Bit-DLLs laden. Ein 32-Bitprozess kann nur 32-Bit-DLLs laden. Die magische Windows-on-Windows- (oder WoW-) Ebene, in der 32-Bit-Anwendungen unter 64-Bit-Windows ausgeführt werden, besteht zwischen dem Benutzermodus-Prozess (EXE und DLLs) und dem Kernel. Es gibt keine Möglichkeit, eine 32-Bit-DLL in einem 64-Bit-Prozess auszuführen. Die WoW-Schicht existiert darunter. (Im Grunde ist WoW ein 32-Bit-Wrapper um die 64-Bit-Win32-API, der Daten- und Funktionsaufrufe zwischen der 32-Bit-Welt des Prozesses und der 64-Bit-Welt des Betriebssystems mars.)

Ihr Bestes/Die einzige Option besteht darin, Ihre 32-Bit- und 64-Bit-Komponenten in separaten Prozessen auszuführen und eine Art von IPC für die Kommunikation zu verwenden. Dies hat den zusätzlichen Vorteil, dass Sie Ihre Kernanwendung von potenziell instabilen Drittanbieterkomponenten entkoppeln. Wenn eine Komponente eines Drittanbieters abstürzt oder sich schlecht verhält, muss der Prozess, der diese Komponente enthält, neu gestartet werden.

+0

Wir haben es bereits in another AppDomain abgesondert, so dass Sicherheit in Ordnung ist. Die Umstellung auf einen anderen Prozess führt zu einer Komplexität der Schnittstelle, die wir vermeiden wollten, aber es scheint entweder so zu sein oder die Hardware von Vendor A aufzugeben. – ctacke

+0

Das ist gut, dass Sie es in einer anderen AppDomain abgesondert haben. Eine AppDomain bietet jedoch nur Sicherheit zwischen verwalteten Code-Komponenten. Unmanaged Code kann fröhlich einen schlechten Zeiger greifen und beginnen, Müll in den gesamten Prozessspeicherbereich unabhängig von AppDomain zu spucken. Sie sollten IPC über Speicherabbilddateien oder eine ähnliche Technik in Erwägung ziehen, damit die Komponenten von Drittanbietern Ihre App nicht zerstören können. :) –

1

Sie können einen separaten 32-Bit-Prozess für die Interaktion mit Anbieter A erstellen und dann mit WCF kommunizieren.

+0

Ja, ich habe versucht, das zu vermeiden - aber es könnte die einzige Zuflucht sein. – ctacke

0

Hoffentlich kann jemand eine bessere Alternative vorschlagen, aber vielleicht könnten Sie eine der Bibliotheken (welche immer die Verbindung mit der niedrigsten Bandbreite zu Ihrer App hat) in einem separaten Prozess umhüllen und dann mit ihr kommunizieren (z. B. über Sockets).

1

Da Sie 32-Bit- und 64-Bit-Bilder nicht in denselben Prozess laden können, müssen Sie eine Multi-Prozess-Lösung verwenden.

Verwandte Themen