Visual Studioの1つのプロジェクトで32ビットと64ビットの両方をターゲットにする

ネイティブなDLLを使って32ビットと64ビット対応のアプリケーションを作る場合、コードは同じだが参照するDLLのパスが違うだけという場合があると思います。例えばSystem.Data.SQLite.dllなど。

Visual Studioのプロジェクトの構成でx86やx64を選んでプラットフォームを変えた時に参照するDLLも同時に変える方法がhttp://stackoverflow.com/questions/145803/targeting-both-32bit-and-64bit-with-visual-studio-in-same-solution-projectに載ってました。

英語だし本筋と関係ない議論もあるので、必要なところだけまとめときます。

以下ではSQLite.dllを使い分ける例を示します。

まずx86構成でプロジェクトを作り、32ビット版のSQLite.dllを参照に加えます。

VSを一旦終了させ、上記のプロジェクトの構成ファイル*.csprojを開くと以下のようになっています。

...
<ItemGroup>
<Reference>...Reference>
<Reference>...Reference>
<Reference Include="System.Data.SQLite, Version=1.0.75.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>FalseSpecificVersion>
<HintPath>..\..\lib\SQLite-1.0.66.0-binaries\bin\System.Data.SQLite.DLLHintPath>
Reference>
<Reference>...Reference>
ItemGroup>
...

ItemGroup要素の中にプロジェクトの参照設定がずらっと並んでいます。HintPathがDLLのパスです。

ここでSQLite.DLLを条件付きのItemGroupでくくって外に出してやります。

<ItemGroup Condition=" '$(Platform)' == 'x86' ">
<Reference Include="System.Data.SQLite, Version=1.0.75.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
<SpecificVersion>FalseSpecificVersion>
<HintPath>..\..\lib\SQLite-1.0.66.0-binaries\bin\System.Data.SQLite.DLLHintPath>
Reference>
ItemGroup>
<ItemGroup Condition=" '$(Platform)' == 'x64' ">
<Reference Include="System.Data.SQLite, Version=1.0.75.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x64">
<SpecificVersion>FalseSpecificVersion>
<HintPath>..\..\lib\SQLite-1.0.66.0-binaries\bin\x64\System.Data.SQLite.DLLHintPath>
Reference>
ItemGroup>
<ItemGroup>
<Reference>...Reference>
<Reference>...Reference>
<Reference>...Reference>
ItemGroup>

こんな風にItemGroup要素を複数定義します。

そしてVSを再起動すると「参照コンポーネント ‘System.Data.SQLite’ が見つかりませんでした」という警告が出ますが、無視してビルドしてみるとプラットフォームの設定毎に適切なDLLがちゃんとロードされます。