2010-01-14 143 views
6

我们正在创建一个围绕非托管DLL的C#包装。非托管DLL包含32位和64位版本。我们将托管包装保存在自己的项目中,以便我们可以将其构建为独立的组件,并在解决方案中重复使用它。为32位和64位非托管DLL创建托管包装

但是这会导致一些问题。由于非托管DLL对于32位和64位版本都具有相同的名称,所以我们在将正确的非托管DLL移动到输出(bin)目录时遇到问题。如果构建配置是x86,我们想要复制32位版本和64位64位的x64。只需一个处理器架构就很容易实现。我们只在我们的项目中包含非托管DLL,并在文件中将本地复制设置为true。但既然我们需要瞄准它的两个更棘手的问题。

我们发现此链接Targeting both 32bit and 64bit with Visual Studio in same solution/project但这似乎引用了一些已存在于机器上的DLL。我们希望将正确版本的DLL复制到输出目录(bin)。

任何有关如何解决这个问题的技巧或技巧都值得欢迎。

回答

1

在这种情况下,您可能想要使用类似MSBuild的控件来控制构建。然后你可以使用一个编译标志来执行32或64位编译。通过这样做,它也可以让你控制你推动哪个dll。这听起来像是你最好的选择。如果你不喜欢msbuild,你也可以使用nant。

1

另一个选择是在Visual Studio中创建除调试和发布之外的新配置....也许是Debug32和Debug64等。其中一个配置设置是CPU体系结构。

然后在你的项目的生成后事件,你可以做一个老式的,如果使用的平台名称宏视病情/ else语句...

或者,如果你使用的平台名称为解决方案中的子目录非托管dll的存储位置,您可以使用平台名称从目录复制到bin目录。

0

如果您将您的配置设置为拥有两个平台,一个用于32位和64位版本。然后你将每个平台的引用设置为正确的dll版本,然后你需要做的就是在你的引用属性上设置复制本地标志,而vsts将为你处理所有这些。没有麻烦没有大惊小怪。

5

我刚刚经历了与FreeImage库的.Net包装相同的问题。我所做的是创建两个构建配置,一个用于x86,一个用于引用托管包装的项目的x64。我加的MSBuild条件的复印部在项目文件的AfterBuild目标,像这样:

<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

嗨,谢谢你的回复。正如您在包装项目的项目文件中所建议的,我们已经实现了afterbuild目标。但是,从引用包装器项目的其他项目中,非托管DLL不会与包装器DLL一起复制到bin目录中。有关如何实现此目的的任何提示? – flalar 2010-01-20 11:48:43

+0

通常,我们为所有间接引用和/或动态加载的程序集所做的操作是使用后构建命令将它们从其项目TargetDir中推送到公共输出文件夹。然后,任何需要它们的项目都会使用前/后生成命令将它们复制到TargetDir。 例如推: XCOPY “$(TARGETDIR)$(TargetFileName)” “$(SolutionDir)PluginOutput \”/ E/Y 例如拉: XCOPY “$(SolutionDir)PluginOutput \ *。dll” 将“$(TARGETDIR )“/ E/Y – duckworth 2010-01-20 18:52:27

+0

你从哪里获得FreeImage DLL的x64版本?我一直在寻找它一段时间,但一个没有接缝存在! – 2010-02-08 19:06:00

1

我们处理这一切都与我们的项目的时间。

我们有一个非托管的C++ DLL,它具有32位和64位版本,以及一个使用P/Invoke调用非托管DLL的C#项目。

对于C++ DLL,它的目标路径是:

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

所以32位发行版本会去的Win32 \释放, 64位调试版本将在x64 \ Debug中进行。

在C#项目中,我们删除'Any CPU'配置,并用新的'x86'配置和'x64'配置替换它。它的输出目录类似于非托管的C++ DLL,除了.NET编译器使用'x86',而C++使用'Win32'来表示32位体系结构可执行文件。

在C#项目的构建后步骤中,我们将相应的非托管DLL复制到C#可执行文件的目标目录中。由于C#项目的每个体系结构和每个配置都有一个单独的输出目录,因此保持直接哪个非托管DLL的体系结构位于哪个输出目录是没有问题的;他们总是匹配。

为了简化这个进一步,我建议你研究构建一个多文件组件(http://msdn.microsoft.com/en-us/library/226t7yxe.aspx),这样你的非托管的DLL和C#的包装既可以驻留在一个单一的.NET程序集,节省您的身边复制它在所有的麻烦。

+0

所以多文件程序集几乎就是一个C#程序集包含x86和x64非托管dll并加载适当的? – flalar 2010-01-20 14:23:52

+0

不完全。 假设您有用C#编写的ManagedAssembly.dll以及C++中NativeAssembly.dll的32位和64位版本。 您可以创建两个多文件程序集,一个包含ManagedAssembly.dll和32位NativeAssembly.dll,另一个包含ManagedAssembly.dll和64位NativeAssembly.dll。这样,您只需要担心一个DLL依赖项,而不是混合架构不可知的和特定于体系结构的DLL。 – anelson 2010-01-20 16:51:58