2010-01-14 16 views
6

Nous créons un wrapper C# autour d'une DLL non managée. La DLL non managée est disponible en versions 32 et 64 bits. Nous conservons le wrapper géré dans son propre projet afin que nous puissions le construire en tant que composant séparé et le réutiliser à travers les solutions.Création d'un wrapper géré pour les DLL non gérées 32 bits et 64 bits

Toutefois, cela entraîne certains problèmes. Comme la DLL non managée a le même nom pour les versions 32 bits et 64 bits, nous avons du mal à déplacer la DLL non managée correcte vers le répertoire de sortie (bin). Si la configuration de construction est x86, nous voulons copier la version 32 bits et avec x64 la version 64 bits. Avec une seule architecture de processeur, c'est facile à réaliser. Nous incluons simplement la DLL non managée dans notre projet et définissons copy local à true sur le fichier. Mais puisque nous devons cibler à la fois son plus délicat.

Nous avons trouvé ce lien Targeting both 32bit and 64bit with Visual Studio in same solution/project mais cela semble faire référence à certaines DLL qui existent déjà sur la machine. Nous voulons que la version correcte de la DLL soit copiée dans le répertoire de sortie (bin).

Tous les conseils ou techniques pour résoudre ce problème sont les bienvenus.

Répondre

1

Vous pourriez vouloir utiliser quelque chose comme MSBuild pour contrôler vos builds dans ce cas. Ensuite, vous pourriez avoir un drapeau de compilation que vous utilisez pour faire la compilation 32 ou 64 bits. En faisant cela, il vous permettra également de contrôler quelle DLL vous appuyez. Cela semble être votre meilleure option. Si vous n'aimez pas msbuild, vous pouvez aussi utiliser nant.

1

Une autre option serait de créer une nouvelle configuration dans Visual Studio en plus de Debug and Release .... peut-être Debug32 et Debug64, etc. L'un des paramètres de configuration est l'architecture de la CPU.

Puis dans votre événements post de projet de construction, vous pouvez faire une ancienne instruction if/else utilisant la macro nom de la plate-forme comme condition ...

Ou si vous avez utilisé le nom de la plate-forme que le sous-répertoire dans votre solution où la DLL non managée était stockée, vous pouviez copier depuis le répertoire en utilisant le nom de la plate-forme vers le répertoire bin.

0

Si vous définissez votre configuration sur deux plates-formes, une pour les versions 32 bits et 64 bits. Ensuite, vous définissez la référence pour chacune des plates-formes à la version de DLL correcte, alors tout ce que vous devez faire est de définir le drapeau local de copie sur vos propriétés de références et les vsts gérera tout pour vous. Pas de problème, pas de problème.

5

Je viens de passer par le même problème avec l'encapsuleur .Net pour la bibliothèque FreeImage. Ce que j'ai fait était de créer deux configurations de construction, une pour x86 et une pour x64 pour le projet qui fait référence à l'encapsuleur géré. J'ai ajouté msbuild sections de copie conditionnelle dans la cible AfterBuild du fichier de projet comme ceci:

<Target Name="AfterBuild"> 
    <Copy Condition="'$(Platform)' == 'X86'" SourceFiles="$(MSBuildProjectDirectory)\Resources\x86\FreeImage.dll" DestinationFolder="$(TargetDir)" /> 
    <Copy Condition="'$(Platform)' == 'X64'" SourceFiles="$(MSBuildProjectDirectory)\Resources\x64\FreeImage.dll" DestinationFolder="$(TargetDir)" /> 
    </Target> 
+0

Salut et merci pour la réponse. Nous avons implémenté la cible afterbuild comme vous l'avez suggéré dans le fichier projet du projet wrapper. Toutefois, à partir d'autres projets référençant le projet wrapper, les DLL non managées ne sont pas copiées dans le répertoire bin avec la DLL d'encapsuleur. Des conseils sur la façon d'y parvenir? – flalar

+0

En général, ce que nous faisons pour tous les assemblages référencés indirectement et/ou chargés dynamiquement est de les repousser de leur projet TargetDir vers un dossier de sortie commun avec une commande post build. Ensuite, tous les projets qui en ont besoin les copient dans leur TargetDir avec une commande pre/post build. exemple pousser: xcopy "$ (TargetDir) $ (TargetFileName)" "$ (SolutionDir) PluginOutput \"/E/Y exemple traction: xcopy "$ (SolutionDir) PluginOutput \ * dll" « $ (TargetDir) "/ E/Y – duckworth

+0

Où avez-vous obtenu la version x64 de FreeImage DLL? Je l'ai cherché depuis un certain temps, mais il n'y a pas de couture existe! –

1

Nous traitons tout le temps avec nos projets.

Nous avons une DLL C++ non managée qui a des versions 32 et 64 bits, et un projet C# qui utilise P/Invoke pour appeler la DLL non managée.

Pour la DLL C++, il est le chemin cible est:

$ (PlatformName) $ \ (NomConfiguration) $ \ TargetName)

Ainsi, la version release 32 bits irait dans Win32 \ Release, et la version de débogage 64 bits irait dans x64 \ Debug.

Dans le projet C#, nous supprimons la configuration 'Any CPU' et la remplaçons par une nouvelle configuration 'x86' et une configuration 'x64'. Ses répertoires de sortie sont similaires aux DLL C++ non managées, sauf que le compilateur .NET utilise 'x86' alors que C++ utilise 'Win32' pour désigner un exécutable d'architecture 32 bits.

Lors de l'étape de post-construction du projet C#, nous copions la DLL non managée appropriée dans le répertoire cible de l'exécutable C#. Puisque chaque architecture et chaque configuration du projet C# a un répertoire de sortie séparé, il n'y a pas de problème pour garder à l'esprit quelle architecture de la DLL non managée est dans quel répertoire de sortie; ils correspondent toujours. Pour simplifier cela, nous vous suggérons d'étudier la construction d'un assemblage multi-fichiers (http://msdn.microsoft.com/en-us/library/226t7yxe.aspx) pour que votre DLL non managée et son wrapper C# puissent tous deux résider dans un seul assemblage .NET, vous évitant ainsi de devoir le copier.

+0

Donc un assemblage multi-fichiers serait à peu près un assemblage C# qui contient à la fois x11 et x64 DLL non géré et charge le approprié? – flalar

+0

Pas exactement. Supposons que ManagedAssembly.dll, écrit en C#, et les versions 32 et 64 bits de NativeAssembly.dll en C++. Vous pouvez créer deux assemblys multi-fichiers, un avec ManagedAssembly.dll et le fichier NativeAssembly 32 bits, et un autre avec ManagedAssembly.dll et le fichier NativeAssembly.dll 64 bits. De cette façon, vous n'avez qu'à vous soucier de la dépendance d'une DLL au lieu d'un mélange de DLL spécifiques à l'architecture et à l'architecture. – anelson