「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
本ページでは、64bitプラットフォーム移行に伴うアプリケーションの環境移行、ポーティング移行の作業範囲を扱います。
- WOW64は、64bitプラットフォーム上でWin32アプリケーションを実行する、エミュレーションレイヤー・サブシステム。
- 64bit版システムファイルを納めた\system32ディレクトリに対応する形で
32bit版ファイルを格納した\SysWOW64ディレクトリのコンポーネントを利用して動作する。
- これにより、32bitアプリケーションはそのまま64bitプラットフォーム上でも動作する。
通常のアプリケーション †
以下に、WOW64を使用する際の注意点を記述する
(詳細は参考の「WOW64 のベスト プラクティス」を参照)。
- 32(64)bitのABIから64(32)bitのABIを呼べないのでどちらかに揃える。
WOW64では32bitのABIに揃える(ABI:実行ファイルやライブラリ)。
- デバイスドライバ類はWOW64を利用できないので64bitに対応した物を準備する。
WOW64上のWin32アプリケーションから利用する場合、ドライバ付属のSDKに32bit用DLLを利用(付属するかはメーカに確認)。
- レジストリ リダイレクトおよび レジストリ リフレクション、 ファイル システムのリダイレクトの機能がある。
SysWOW64ディレクトリのコンポーネントを利用するのもファイル システムのリダイレクトの機能。
- ファイルや変数への参照が原因で、問題が発生する場合がある。
(システム変数、環境変数、KNOWNFOLDERID値、および Sysnativeエイリアスを含むファイル システム パス フォーム)
- その他、WOW64の制限事項
- アドレス空間は既定で2.0GBである。
- 16bitプロセスの実行はサポートされない。
- 仮想DOSマシン(VDM)APIは無効化される。
- AWE(Address Windowing Extensions)、スキャッター/ギャザーI/O、
書き込み追跡など、ページサイズに依存するAPIは、IPF上では利用できない。
- PAE(Physical Address Extension)は、IPF上では利用できない。
- DirectX、ハードウェア アクセラレータAPIは、IPF上ではサポートされない。
※ IPF:Itanium Processor Family
Webアプリケーション †
IIS †
IISのワーカプロセス(ASPやASP.NETなどのWebアプリケーションがホストされる)も32bit(WOW64)をサポートする。
IIS Express †
IIS Expressを64bitで動作させることも可能。
- Visual Studioのメニューから[ツール] - [オプション]を開く
- [プロジェクトおよびソリューション] - [Web プロジェクト]を開く
- [Web サイトおよびプロジェクト用 IIS Express の64ビットバージョンを使用]のチェックをONにする
レガシーASP †
なお、レガシーASPは、32bit(WOW64)もサポートしてます。
ただし、殆どの場合は、使用するCOMが 32bitのVB COMで開発されているので、
WOW64上で32bitアプリケーションとして動作させることとなります。
VC++ †
データモデル †
最も大きな問題は32bit、64bit間のデータモデルの変更である。
以下、64プラットフォームのデータモデルについて説明する。
今日では、多くの64bitコンパイラがLP64モデルを採用している
(Solaris、AIX、Mac OS X、z/OS のネイティブコンパイラなど)が、
マイクロソフトのVC++コンパイラはLLP64モデルを採用している。
- LP64モデルの欠点
long型データをint型変数に代入するときにオーバーフローが発生する可能性がある点である。
- 一方、LLP64モデルの欠点
ポインタをlong型にcastできないためlong long型(VC++コンパイラではINT64、__int64、LONGLONG)を使用する必要がある点である。
64bitデータモデル
データモデル | short | int | long | longlong | ポインタ | 処理系 |
LLP64 | 16 | 32 | 32 | 64 | 64 | Microsoft Win64 (X64/IA64) |
LP64 | 16 | 32 | 64 | 64 | 64 | ほとんどのUnixとUnix風OS (Solaris, Linux, etc.) |
IP64 | 16 | 64 | 32 | 64 | 64 | ? |
ILP64 | 16 | 64 | 64 | 64 | 64 | HAL |
SILP64 | 64 | 64 | 64 | 64 | 64 | ? |
詳しくは、下記の参考を参照。
64bit COM †
- 必要に応じて64bit用VC++コンパイラを追加インストール、構成マネージャから64bit用のプラットフォームを新規作成することで64bit COMを作成可能。 ポインタをlong型にcastするようなコードが無ければストレート移行が可能である。ATL COMの場合、CComPtr?、CComBSTRなどのスマート ポインタ クラスを使用して、 ポインタを直接使わないことが多いので32bit COM → 64bit COM移行はそれほど難しくないと考える。
- また、Regsrv32する際に、(恐らくPEヘッダを参照することで、)自動的に 「COMの生成情報」の登録先であるレジストリを標準(64bit用)とするか、WOW64(32bit用)とするかの切り替えが為される。 そして、COMを生成するときは、呼出元プロセスが64bit or 32bit(WOW64)によって「COMの生成情報」が格納されている 参照先レジストリが切り替えられるため、適切なCOM(64bit or 32bit)を生成することができる。
- このため、ADODBなどのミドルウェアも、64bitサポートがされていれば(64bit用、32bit用の双方のDLLがRegsrv32されていれば)、 64bit or 32bit(WOW64)の双方のプロセスから利用することができる(余談:WSHのWscript.exe・Cscript.exeも64bit用、32bit用の双方が用意されている)。
- また、.NETではAny CPUのコンパイルが可能なので、64bit・32bitを意識しないこともありますが、 アンマネージコードと連携する場合は.NETの呼出元プロセスが64bit or 32bitのどちらで動作しているか注意が必要です。 なお、VS2010からEXEを作るプロジェクトのデフォルトがAny CPUからx86に変更されています(詳しくは下記参照)。
.NET、ASP.NET †
以下、.NETのアプリケーションの64bit対応のポイントについて説明する。
100%タイプ セーフな場合 †
100%タイプ セーフなマネージ コードであれば、そのまま移行可能。
- 100%タイプ セーフとは?
- DLL(platform)呼び出し、COM呼び出しをしていないこと。
- /clr:safeオプションでコンパイルされており、低レベルな処理の実行が許可されていないこと。
- ポインタの宣言と処理
- ポインタと整数型の変換
- 変数のアドレス取得
100%タイプ セーフでない場合 †
100%タイプ セーフでない場合は、Windowsの64bitプラットフォームがLLP64モデルであることを意識してコードを書きなおす必要がある。
- IntPtr?.Sizeを使用してプラットフォームを識別可能。
- ポインタを受け取る場合は、IntPtr?型を使用する。
- Marshalクラス を用いてデータのマーシャリングを行う場合は、メモリの境界整列(アライメント)を考慮する必要がある。
- LayoutKind?.Sequentialを使用する場合は、StructLayoutAttribute?.Pack
- LayoutKind?.Explicitを使用する場合は、FieldOffsetAttribute?
- BinaryFormatter?クラス を使用したバイナリ・シリアライズは、
IntPtr?を保存して32bit⇔64bitプロセス間を跨ぐ場合にのみ問題を起こす。
- 32bitのCOMは、tlbimp.exeを使用して64bit用のRCWを生成することで、
WOW64でホストされる32bitアウトプロセスを呼び出し可能。
- 64bit用のRCWを生成する:tlbim.exe foo.dll/machine:x64/out:Interop.Foo.dll
- 32bitのCOMを登録する。:regsvr32.exe foo.dll
- 下記のコンパイル オプションをx64、Itaniumに変更してRCW(Interop.Foo.dll)を参照設定。
- C#のアンセーフコード、C++/CLIは問題が起こらないか見直しが必要になる。
コンパイル オプション(構成のtarget platform) †
- コンパイル オプション(構成のtarget platform)をanyCPUか、x64、Itaniumに変更する。
- .NET Framework2.0以降からのサポート。.NET Framework1.0、1.1は WOW64上で実行する。
- アセンブリに指定されてるコンパイル オプション(構成のtarget platform)を調査する方法
ILDASM.exeを使用して、PEヘッダ(ILDASM(UI)のメニューから、表示 → ヘッダーを選択して表示される)のCOFF Header の Machine Type を確認する。
既定値 †
- VS2010
EXE を作るプロジェクトのデフォルトが Any CPU から x86 に変更されている。
- アーキテクチャ中立のAnyCPU EXE は通常、価値よりもトラブルのほうが多くコスト高。
- 32ビットはいずれにしろより速い傾向がある。
- いくつかの機能が64ビットでは利用できない。
- VS2012以降
- しかし、VS2012以降では、再び、デフォルトはAny CPUに戻っている。
- 恐らく、製品以外の用途での利用が多く、ソレには、Any CPUが適していたのだと思う。
- また、ODP.NET Managed Driverなどでも、Any CPUの利用が一般的になってきている。
参考 †
WOW64 †
Microsoft †
- Windows ハードウェア デベロッパー センター:WOW64 のベスト プラクティス
http://msdn.microsoft.com/ja-jp/windows/hardware/gg463051
- ファイル システム リダイレクトはスレッド単位であるため、リダイレクトの無効化が必要なオペレーションは別スレッドに分離する。
- タスクの実行後、できるだけ速やかにリダイレクトを再度有効化する。
- 64 ビット プロセスを 32 ビット バージョンのプロセスと同時にインストールする場合は、相互運用性に注意する。
- ソケット、パイプ、RPC、および COM といったプロセス間コミュニケーションを使用する場合は、データの処理におけるビット幅別の対応状況をチェックする。
- 32 ビット プロセスから64 ビット プロセスへのアクセスを避ける。
その他 †
移行 †
MSDN †
- Visual Studio ドキュメント > Visual C++
- Windows 開発 > 64 ビット Windows プログラミング ガイド
- テクニカルドキュメント > .NET 開発 > 技術資料
- MSDN Blogs > とあるコンサルタントのつぶやき
- 64ビットコンピューティング最前線:64ビットになると何が変わる?
Tags: :移行, :.NET開発