QA@IT

.NET の動作プロセスについて

5935 PV

現在 P/Invoke を利用する .NET アプリケーション(以下AP1)と通常の .NETアプリケーション(以下AP2)を作成しています。
これらのアプリケーションは Windows XP や Windows 7 などで動く必要があり、現在はx86だけサポートしますが、
将来的にx64もサポートしなければなりません。
P/Invoke する対象のネイティブDLLは、x64版、x86版ともに提供されています。

そこで質問なんですが、正しい.NETアプリケーションのTargetCPUとネイティブDLLの組み合わせ、
その時の動作プロセスを教えて下さい。

自分では以下のような組み合わせであれば動作するのではないかと考えています。

  • x86版OS→すべて32bitプロセス
    1. TargetCPU:AnyCPUでビルドした AP1 + x86版ネイティブDLL
    2. TargetCPU:x86でビルドした AP1 + x86版ネイティブDLL
    3. TargetCPU:AnyCPUでビルドした AP2
    4. TargetCPU:x86でビルドした AP2
  • x64版OS→WOW64で動作する32bitプロセスまたは64bitプロセス
    1. TargetCPU:AnyCPUでビルドした AP1 + x64版ネイティブDLL→64bitプロセス
    2. TargetCPU:x86でビルドした AP1 + x86版ネイティブDLL→WOW64で動作する32bitプロセス
    3. TargetCPU:x64でビルドした AP1 + x64版ネイティブDLL→64bitプロセス
    4. TargetCPU:AnyCPUでビルドした AP2→64bitプロセス
    5. TargetCPU:x86でビルドした AP2→WOW64で動作する32bitプロセス
    6. TargetCPU:x64でビルドした AP2→64bitプロセス

回答

動作するのではないかとして挙げられた、すべてのケースについて想定された通りに動作します。

少し面倒ですが、AnyCPUでビルドした.NETアプリケーションから、x86とx64のネイティブDLLのいずれかをLoadLibraryで読み込んで、DLLの提供する関数を呼ぶことは可能です。

LoadLibraryで読み込んだネイティブDLLの関数を.NETから呼ぶ手順は、MSDN BlogsのDynamically calling an unmanaged dll from .NET (C#)に載っています。

LoadLibraryのところで、.NETアプリケーションが32bitで動作しているならx86のDLLを、64bitならx64のDLLを読み込みます。AnyCPUでビルドしたアプリケーションがどちらで動作しているかを調べる方法は、「アプリケーションが64ビットで動いているか調べる」に載っています。

編集 履歴 (1)
  • 回答ありがとうございます。なるほど、そういう見分け方があるんですね。勉強になります。もしご存知の場合、情報ソースへリンクしてもらえないでしょうか。 -
  • 64bitかどうかの判定方法はhttp://dobon.net/vb/dotnet/system/is64bit.htmlを参考にしました。 -

そもそもネイティブのDLLやCOMコンポーネントとのInteropでAnyの選択肢はないものと思ってください。

32bitで作るか64bitで作るかです。

COMもInterop Assemblyがx86とx64では異なります。

両方のサポートが必要であれば、プロジェクトを分けて、純粋な.NETのコードの部分だけコード共有をするか、逆に共有できる.NETの部分の方をライブラリ化してしまうかと行った方法を考えた方が良いのでは。

編集 履歴 (0)
  • 回答ありがとうございます。
    なるほど、そうするとx86版OSで1が、x64版OSでも1がよろしくない選択肢ということですね。ピュア.NETはAnyでも大丈夫なのでしょうか?起動アセンブリがx86で、そこから ピュア.NET: Any, P/Invoke:x86を参照するという構成または起動アセンブリ:x64からピュア.NET:AnyとP/Invoke:x64を参照するという構成ですかね。
    -
  • 完全に.NETだけの場合はAnyでもかまいません。Anyの場合はx64OSであればx64で動きます。 -
  • ありがとうございます。 -
ウォッチ

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