7
votes

Création d'une enveloppe gérée pour la DLL non exploitée de 32 bits et 64 bits

Nous créons une enveloppe C # autour d'une DLL non gérée. La DLL non gérée entre une version 32 et 64 bits. Nous gardons l'emballage géré dans son propre projet afin que nous puissions la construire comme un composant distinct et la réutiliser à travers des solutions.

Cependant, cela conduit à certains problèmes. Étant donné que la DLL non gérée a le même nom pour les versions 32 bits et 64 bits, nous avons du mal à déplacer la DLL correcte non gérée dans le répertoire de sortie (bin). Si la configuration de construction est x86, nous voulons copier la version 32bit et avec x64 le 64 bits. Avec une seule architecture de processeur, il est facile à réaliser. Nous incluons simplement la DLL non gérée dans notre projet et définir la copie locale sur true sur le fichier. Mais puisque nous devons cibler à la fois que c'est plus délicat.

Nous avons trouvé ce lien ciblage 32 bits et 64 bits avec Visual Studio dans la même solution / projet , mais cela semble faire référence à une DLL qui existe 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 sur la manière de résoudre ce problème sont plus que les bienvenus.


0 commentaires

5 Réponses :


1
votes

Vous voudrez peut-être rechercher quelque chose comme Msbuild pour contrôler vos constructions 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, cela vous permettrait également de contrôler la DLL que vous appuyez. Cela ressemble à votre meilleure option. Si vous n'aimez pas Msbuild, vous pouvez également utiliser Nant.


0 commentaires

1
votes

Une autre option serait de créer une nouvelle configuration dans Visual Studio, outre le débogage et la libération ... peut-être debug32 et Debug64, etc. L'un des paramètres de configuration est l'architecture du processeur.

Ensuite, dans les événements de votre projet de construction, vous pouvez effectuer une instruction à l'ancienne à l'ancienne si / else à l'aide de la macro de nom de la plate-forme comme condition ...

ou si vous avez utilisé le nom de la plate-forme comme sous-répertoire dans votre solution où la DLL non gérée a été stockée, vous pouvez copier à partir du répertoire à l'aide du nom de la plate-forme sur le répertoire bin.


0 commentaires

0
votes

Si vous définissez votre configuration pour avoir 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 DLL correcte, alors tout ce que vous avez à faire est de définir le drapeau local de copie sur vos propriétés de références et VSTS les traitera tout pour vous. Pas de muss no contre.


0 commentaires

5
votes

Je viens de passer à travers ce même problème avec le wrapper .NET pour la bibliothèque de 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'emballage géré. J'ai ajouté Msbuild Sections de copie conditionnelle de Msbuild dans la cible Afterbuild du fichier de projet, comme:

  <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>


4 commentaires

Salut et merci pour la réponse. Nous avons mis en place la cible de l'après-capuce comme vous l'avez suggéré dans le fichier de projet du projet Wrapper. Toutefois, des autres projets qui font référence au projet Wrapper, la DLL non gérée n'est pas copiée dans le répertoire des bin avec la DLL de wrapper. Des conseils sur la manière de y parvenir?


Généralement, ce que nous faisons pour tous les assemblages référencés indirectement référencés et / ou dynamiquement les poussent de leurs projets TargetDir dans un dossier de sortie commun avec une commande de publication. Ensuite, tous les projets qui ont besoin d'eux les copier sur leur TargetDir avec une commande Pre / Post Build. Exemple Push: XCopy "$ (Targedir) $ (TargetFilename)" "$ (SolutionDir) PluginOutputput \" / E / Y Exemple Tirez: xcopy "$ (solutiondir) pluginoutputtput * .dll" $ (Targedir) "/ e / y


Où avez-vous obtenu la version X64 de FreeImage DLL? Je la cherchais depuis un certain temps, mais on n'existe pas!


@sansegot: La version X64 de FreeImage n'existe pas, vous devez la construire par vous-même, http://www.sambeauvois.be/blog/2010/05/freeimage-and-x64-pro Jects-Yes-You-Can /



1
votes

Nous traitons tout le temps avec nos projets.

Nous avons une DLL c ++ non gérée qui contient des versions 32 et 64 bits et un projet C # qui utilise p / invoke pour appeler la DLL non gérée.

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

$ (plateformeNameName) \ $ (configurationName) \ $ cibleName)

La construction de la version 32 bits irait dans Win32 \ version, et la construction de débogage 64 bits irait en X64 \ débogage.

Dans le projet C # Nous supprimons la configuration "Toute CPU", puis remplacez-la par une nouvelle configuration "x86" et une configuration 'x64'. Ses répertoires de sortie sont similaires à ceux de la DLL C ++ non gérés, sauf que le compilateur .NET utilise 'x86' tandis que C ++ utilise 'Win32' pour désigner une architecture 32 bits exécutable.

Dans l'étape post-construction du projet C #, nous copions la DLL non gérée appropriée dans le répertoire cible de l'exécutable C #. Étant donné que chaque architecture et chaque configuration du projet C # dispose d'un répertoire de sortie séparé, il n'y a pas de problème à rester droit quelle architecture de la DLL non exploitée est dans laquelle répertoire de sortie; ils correspondent toujours.

Pour simplifier cela plus loin, je vous suggère d'enquêter sur la construction d'un ensemble multi-fichiers ( http://msdn.microsoft.com/en-us/library/226t7yxe.aspx ) Votre DLL non gérée et votre enveloppe C # peuvent tous les deux résider dans un seul assemblage .NET, vous sauver le tracas de la copie du tout.


2 commentaires

Ainsi, un ensemble multi-filets serait à peu près une assemblée C # contenant à la fois une DLL X86 et X64 et chargées le plus approprié?


Pas exactement. Dites que vous avez managedassembly.dll, écrit en C # et les versions 32 et 64 bits de NativeAssembly.dll en C ++. Vous pouvez créer deux ensembles de fichiers multiples, un avec gatreDassembly.dll et 32 ​​bits NatinBbly.dll, et un autre avec garesDassembly.dll et le 64 bits NatinBbly.dll. De cette façon, il vous suffit de vous inquiéter de la dépendance d'une DLL au lieu d'un mélange de DLL d'architecture-agnostique et d'architecture.