2010-01-14 162 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