QA@IT

ターゲットCPUがAnyCPUではないアセンブリを、CPUに応じて動的にロードしたい

4291 PV

現在C#で書かれた x86 アプリケーションの x64 対応をしています。検討した結果、WOW64は利用しないことにしました。
そこで以下の様なアセンブリを1プロジェクトで同時に使うにあたり、良い方法がないか検討しています。

  • ネイティブDLL(x86, x64の両方用意されていて、ファイル名は同じ)をP/Invokeで実行するアセンブリ(以下ネイティブアセンブリと表記)
  • ターゲットCPUがx86またはx64のアセンブリ(例:Sysem.Data.SQLite)(以下CPU固定アセンブリと表記)

理想的には、AnyCPUな1プロジェクトで以下の様なかたちを実現したいです。何か良い方法はないでしょうか?

  • x86OSでAnyCPUなプロジェクトを実行すると、x86なネイティブアセンブリをロード
  • x86OSでAnyCPUなプロジェクトを実行すると、x86用CPU固定アセンブリをロード
  • x64OSでAnyCPUなプロジェクトを実行すると、x64なネイティブアセンブリをロード
  • x64OSでAnyCPUなプロジェクトを実行すると、x64用CPU固定アセンブリをロード

※プロジェクトを2つに分けてターゲットCPUを固定すれば簡単ですが、二重管理になってしまうので避けたいです。

以下調査した結果です。AnyCPUでないなら1プロジェクトで管理できそうです。
ネイティブアセンブリの場合、x86用DLL配置ディレクトリとx64用DLL配置ディレクトリを用意して、SetDllDirectoryでDLL検索場所をCPUに応じて動的にセットすればいいかと思います。
CPU固定アセンブリの場合は良い方法が見つかりません。ビルド時に参照アセンブリを変更する方法は見つけましたが、x86用とx64用に成果物を別管理する必要があるので、求めている解決方法ではありません。

  •  「そこで以下の様なアセンブリを1プロジェクトで同時に使うにあたり、良い方法がないか検討しています。」とのことですが、何について良い方法を検討していらっしゃるのでしょう?
    というのも、タイトルには「CPU に応じて動的にロードしたい」とあります。質問文は、プロジェクトを管理する方法のように思われます。この二つは違うものです。
    -
  • 回答ありがとうございます。おっしゃる通り、意図が伝わりにくいと思いますが、良いタイトルが思いつきませんでした。
    CPU固定アセンブリはプロジェクト管理の方法ですが、ネイティブアセンブリの場合はロード方法です。この2つを表す言い方が思いつけばよかったんですが・・・
    -

回答

AnyCPUでビルドして

IntPtr.Size4ならx86
8ならx64

で動作していると判断出来るので
このチェックを行って対象となるDLLを動的にLoadすると良いかと思います。

編集 履歴 (0)
  • 回答ありがとうございます。反応が遅くなってすいません。
    x86とx64の区別はご教授いただいた方法で大丈夫だと思います。
    できればCPU固定アセンブリの場合にどうすればいいか、が知りたいです。
    -
  • CPU固定アセンブリということはx86とx64のプロジェクトを別に作るということになりますが、それならプロジェクト毎に対象CPUが分かっているのだから普通に出来るのでは?理想はAnyCPUって書いてありますが話がよく分からなくなりました。 -
  • 反応が遅くなってすいません。見逃してました。
    CPU固定アセンブリはOSSのライブラリです。改変するのは手間なので避けたいです。エントリポイントとなるアセンブリは自作ですが、x86とx64の2つを作りたくありません。
    -
  • >x86とx64の2つを作りたくありません
    ということはやはりAnyCPUでビルドすれば良いのでは?
    実行時にどちらのCPUで動作しているかは前述の判断で可能なので
    後は動的にDLLをロードする方法で実装するとよいと思います。動的にロードするのは別の話になると思いますので、提示された問題は解決で良さそうなきがします。
    -
  • ネイティブアセンブリだけであれば解決なんですが、CPU固定アセンブリがあるため、AnyCPUでビルドするだけでは解決できないです。
    -
  • AnyCPUビルドなら実行環境によって動作モードが変わるのでCPUに合ったCPU固定アセンブリのロードは可能なはずです。あくまでも参照設定ではなく動的ロードですよ?(Assembly.LoadFrom など)
    http://msdn.microsoft.com/ja-jp/library/1009fa28(v=vs.80).aspx
    -
  • すいません。タイトルに動的ロードって書いてましたね。
    開発時は参照設定が必要なんですが、実行時はアセンブリを動的にロードしたい、というのをタイトルにすべきでした。ともあれご教授頂いた方法でロードできるので解決とさせていただきます。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。