2010-05-10 7 views
12

J'ai un projet qui doit être compilé et exécuté en mode 64 bits. Malheureusement, je dois faire appel à une DLL qui n'est disponible qu'en mode 32 bits, donc je ne peux pas tout héberger dans un projet 1 Visual Studio. Je travaille pour trouver le meilleur moyen d'envelopper la DLL 32 bits dans son propre exe/service et émettre des appels à distance (bien que sur la même machine) à cet exe/service de mon application 64 bits. Mon OS est Win7 Pro 64 bits.Façons d'accéder à une DLL 32 bits à partir d'un exe 64 bits

Les appels requis pour ce processus 32 bits sont plusieurs dizaines par seconde, mais le volume de données est faible. Il s'agit d'une application d'analyse d'image en temps réel, ce qui fait que le temps de réponse est critique malgré le faible volume. Beaucoup d'envoi/réception de primitives uniques.

Idéalement, j'hébergerais un service WCF pour héberger cette DLL, mais dans un système d'exploitation 64 bits, on ne peut pas forcer le service à s'exécuter en tant que x86! Source. C'est vraiment dommage car j'ai chronométré les appels de fonction au service WCF pour être seulement 4ms sur ma machine.

J'ai expérimenté avec des tubes nommés est .net. Je les ai trouvés 40 à 50 fois plus lent que WCF (inutilisable pour moi).

D'autres options ou suggestions pour la meilleure façon d'aborder mon puzzle?

+0

Voir [cette réponse] (http://stackoverflow.com/a/12938217/184528) pour une liste plus complète des techniques d'accès DLL 32 bits à partir d'applications 64 bits . – cdiggins

Répondre

9

Comme vous le notez correctement, il n'y a aucun moyen de mélanger la résolution dans le même processus. Vous avez besoin d'un processus séparé pour votre partie 32 bits. Je pense que l'hébergement d'un service WCF est la bonne solution. Votre lien ne parle que de wcfsvchost. Je suis sûr que vous pouvez créer votre propre service Windows, et héberger le service WCF dans ce 32 bits.

Voir ce lien: How to host a WCF service in a managed application. Vous pouvez héberger votre service dans n'importe quelle application gérée, y compris un service Windows, et l'exécuter avec la vitesse souhaitée.

C'est la quantité de code nécessaire à l'auto-hôte un service WCF dans votre application, en supposant que vous venez de créer un nouveau service appelé MyService et la configuration correspond le a été ajouté à App.Config:

class Program 
{ 
    static void Main(string[] args) 
    { 
     using(ServiceHost host = new ServiceHost(typeof(MyService), new Uri[0])) 
     { 
      host.Open(); 
      Console.ReadKey();  
     } 
    } 
} 

Le programme ci-dessus s'exécutera tout aussi bien, même si vous le compilez explicitement en 32 ou 64 bits.

+0

Pourriez-vous élaborer un peu? Je vois que je peux créer un service Windows 32 bits, comment pourrais-je créer un service WCF pour faire l'E/S pour mon service Windows 32 bits? – bufferz

+0

Merci driis! Je ne savais pas que vous pouviez héberger les services WCF manuellement à partir d'une application. C'est une bien meilleure solution que celle que je pensais utiliser. * lève le poing dans les airs * – bufferz

+0

Oh, et juste au cas où vous rencontreriez des problèmes de sécurité, voici un lien: http://blogs.msdn.com/amitlale/archive/2007/01/29/addressaccessdeniedexception-cause-and- solution.aspx – driis

4

Aucune. Point. Dll 32 bits dans le processus 64 bits = pas de go. Ce que je fais est d'exécuter un processus de wrapper 32 bits et de communiquer avec lui en utilisant WCF - un peu comme vous le faites. Je peux forcer l'OS à fonctionner 32 bits.

J'ai une bibliothèque de base (Tradex.Connectivity.Core), avec le code .NET indépendant de la plate-forme. J'ai deux wrappers (Wrapper32.exe, Wapper64.exe) qui démarrent et chargent le code indépendant, puis chargent la classe (C++ géré). Fonctionne comme un charme. C'est à peu près le seul moyen pour moi - vous ne pouvez pas charger des éléments 32 et 64 bits.

+0

"Ce que je fais est d'exécuter un processus de wrapper 32 bits et de communiquer avec lui en utilisant WCF - un peu comme vous le faites.Je peux forcer l'OS à exécuter 32 bits." Comment avez-vous réussi à faire fonctionner votre service WCF en mode 32 bits sur un système d'exploitation 64 bits? Définir la cible de la plate-forme sur x86 renvoie BadImageFormatException et je n'ai pas réussi à trouver un moyen de contourner ce problème. – bufferz

+0

Pourquoi est-ce que ça m'intéresse? Je veux dire, WCF est basé sur le réseau de toute façon. Une fois que le contenu est sérialisé, il n'y a plus de mode 32 ou 64 bits. Oh, et moi-même - pas de wcfsvdhost, je commence mon propre hébergement dans mon exe. Seulement quelques lignes de code. – TomTom

+0

Merci TomTom, je ne savais pas que vous pouviez héberger des éléments WCF en dehors des projets de modèles WCF. Depuis que vous avez demandé "pourquoi est-ce que je m'en soucie?" Je dois souligner que je ne pouvais littéralement pas compiler un projet de modèle WCF 32 bits qui enveloppait une DLL 32 bits. Juste le modèle si, l'auto-hébergement fonctionne. Merci encore. – bufferz

1

Je sais que cette réponse est peut-être un peu en retard, mais il y a quelque temps, je faisais face au même problème (chargement d'une DLL 32 bits dans un assemblage AnyCPU sur une machine 64 bits).

En tant que solution, j'ai écrit le LegacyWrapper. Il se compose essentiellement d'un exe wrapper 32 bits chargeant la DLL souhaitée, communiquant avec votre application via Named Pipes.

Un appel ressemblerait à ceci:

// Define delegate matching api function 
private delegate int GetSystemMetrics(int index); 

// Create new WrapperClient 
// Remember to ensure a call to the Dispose()-Method! 
using (var client = new WrapperClient()) 
{ 
    // Make calls providing library name, function name, and parameters 
    int x = (int)client.Invoke<GetSystemMetrics>("User32.dll", "GetSystemMetrics", new object[] { 0 }); 
    int y = (int)client.Invoke<GetSystemMetrics>("User32.dll", "GetSystemMetrics", new object[] { 1 }); 
} 

Pour certains détails, vous pouvez consulter cette blog post.

Edit:Since Version 2.1, LegacyWrapper also supports loading 64bit DLLs from a 32bit process.

Questions connexes