2010-01-14 19 views
6

Estamos creando un contenedor C# alrededor de una DLL no administrada. La DLL no administrada viene en versiones de 32 y 64 bits. Mantenemos el contenedor administrado en su propio proyecto para que podamos construirlo como un componente separado y reutilizarlo en todas las soluciones.Crear un contenedor administrado para DLL no administrado de 32 bits y 64 bits

Sin embargo, esto genera algunos problemas. Como la DLL no administrada tiene el mismo nombre para las versiones de 32 bits y de 64 bits, tenemos problemas para mover la DLL no administrada correcta al directorio de salida (bin). Si la configuración de compilación es x86, queremos copiar la versión de 32 bits y con x64 la de 64 bits. Con solo una arquitectura de procesador, esto es fácil de lograr. Simplemente incluimos la DLL no administrada en nuestro proyecto y establecemos que copy local sea verdadero en el archivo. Pero como necesitamos apuntar a ambos, es más complicado.

Encontramos este enlace Targeting both 32bit and 64bit with Visual Studio in same solution/project pero esto parece hacer referencia a una DLL que ya existe en la máquina. Queremos que la versión correcta de la DLL se copie en el directorio de salida (bin).

Cualquier consejo o técnica sobre cómo resolver esto son más que bienvenidos.

Respuesta

1

Es posible que desee considerar el uso de algo como MSBuild para controlar sus compilaciones en este caso. Entonces podría tener un indicador de compilación que use para compilar 32 o 64 bits. Al hacer esto, también te permitiría controlar qué dll presionas. Esta parece ser tu mejor opción. Si no te gusta msbuild, también puedes usar nant.

1

Otra opción sería crear una nueva configuración en Visual Studio además de Debug and Release ... quizás Debug32 y Debug64, etc. Una de las configuraciones es la arquitectura de la CPU.

Luego, en eventos posteriores a la construcción de su proyecto, puede hacer una pasada de moda si else/utilizando el nombre de la plataforma macro como la condición ...

O si ha utilizado el nombre de la plataforma como el subdirectorio en su solución donde se almacenaba el dll no administrado, se podía copiar desde el directorio usando el nombre de la plataforma al directorio bin.

0

Si configura su configuración para tener dos plataformas, una para las versiones de 32 bits y 64 bits. Luego, establece la referencia para cada una de las plataformas en la versión dll correcta, entonces todo lo que necesita hacer es establecer la bandera local de copia en sus propiedades de referencias y vsts lo manejará todo por usted. Sin despeinarse sin problemas.

5

Acabo de pasar por este mismo problema con .Net wrapper para la biblioteca FreeImage. Lo que hice fue crear dos configuraciones de compilación, una para x86 y otra para x64 para el proyecto que hace referencia al contenedor administrado. He añadido secciones copia condicional msbuild en el objetivo AfterBuild del archivo de proyecto, así:

<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

Hola y gracias por la respuesta. Implementamos el objetivo de construcción posterior como sugirió en el archivo de proyecto del proyecto de envoltura. Sin embargo, desde otros proyectos que hacen referencia al proyecto contenedora, la DLL no administrada no se copia en el directorio bin junto con la DLL contenedora. ¿Algún consejo sobre cómo lograr esto? – flalar

+0

En general, lo que hacemos para todos los ensamblados con referencia indirecta y/o carga dinámica es empujarlos desde sus proyectos TargetDir a una carpeta de salida común con un comando de compilación posterior. Luego, cualquier proyecto que lo necesite los copiará en su TargetDir con un comando pre/post build también. ejemplo empuje: xcopy "$ (TargetDir) $ (TargetFileName)" "$ (SolutionDir) PluginOutput \"/E/Y ejemplo tirón: xcopy "$ (SolutionDir) PluginOutput \ * dll" "$ (TargetDir) "/ E/Y – duckworth

+0

¿De dónde sacaste la versión x64 de FreeImage DLL? Lo he estado buscando por un tiempo, ¡pero uno no tiene sentido! –

1

Nos ocupamos de esto todo el tiempo con nuestros proyectos.

Tenemos una DLL de C++ no administrada que tiene versiones de 32 y 64 bits, y un proyecto de C# que utiliza P/Invoke para llamar al DLL no administrado.

Para la DLL de C++, que es una ruta de destino es:

$ (PlatformName) \ $ (ConfigurationName) \ $ TargetName)

Así que la versión de lanzamiento de 32 bits iría en Win32 \ Release, y la compilación de depuración de 64 bits iría en x64 \ Debug.

En el proyecto C# eliminamos la configuración 'Cualquier CPU', y la reemplazamos con una nueva configuración 'x86' y una configuración 'x64'. Sus directorios de salida son similares a los DLL C++ no administrados, excepto que el compilador .NET usa 'x86' mientras que C++ usa 'Win32' para denotar un ejecutable de arquitectura de 32 bits.

En el paso posterior a la compilación para el proyecto C# copiamos la DLL apropiada no administrada en el directorio de destino para el ejecutable C#. Como cada arquitectura y cada configuración del proyecto C# tiene un directorio de salida separado, no hay problema para mantener la arquitectura del DLL no administrado en el directorio de salida; siempre coinciden.

Para simplificar esto, le sugiero que investigue la creación de un ensamblado de archivos múltiples (http://msdn.microsoft.com/en-us/library/226t7yxe.aspx) para que su DLL no administrada y su contenedor C# puedan residir en un único ensamblado .NET, ahorrándole la molestia de copiarlo.

+0

Por lo tanto, un ensamblaje de archivos múltiples sería prácticamente un ensamblaje C# que contiene dll no administrado x86 y x64 y carga el apropiado? – flalar

+0

No exactamente. Digamos que tiene ManagedAssembly.dll, escrito en C#, y las versiones de NativeAssembly.dll de 32 y 64 bits en C++. Puede crear dos ensamblajes multi-archivos, uno con ManagedAssembly.dll y el NativeAssembly.dll de 32 bits, y otro con ManagedAssembly.dll y el NativeAssembly.dll de 64 bits. De esta manera, solo tendrá que preocuparse por la dependencia de DLL en lugar de una combinación de DLL independientes de arquitectura y específicos de la arquitectura. – anelson

Cuestiones relacionadas