「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>移行・マイグレーション]]
-戻る
--[[移行・マイグレーション]]
--[[Windows OSの基礎的トピック]]

* 目次 [#c4e2c135]
#contents

*概要 [#x343af64]
本ページでは、64bitプラットフォーム移行に伴うアプリケーションの環境移行、ポーティング移行の作業範囲を扱います。 

*[[WOW64]] [#x0ebf5a3]
-[[WOW64]]は、64bitプラットフォーム上でWin32アプリケーションを実行する、エミュレーションレイヤー・サブシステム。 
-64bit版システムファイルを納めた\system32ディレクトリに対応する形で~
32bit版ファイルを格納した\SysWOW64ディレクトリのコンポーネントを利用して動作する。
-これにより、32bitアプリケーションはそのまま64bitプラットフォーム上でも動作する。

-構造
--WOW64ホストプロセスによって予約された4GBの仮想空間に32ビットABIのコードを読み込み、
--そこで発生したWin64 APIに変換可能なAPI呼び出しを変換して、Win64サブシステムに伝達する。
--構造体の変換は自動的に行われ、Win32側では現在動作しているOSが32ビットシステムか、64ビットシステムかを意識する必要は全くない。
--またユーザーモードで動作するコンポーネント群は32ビット版と64ビット版が用意され、例えばOLEなどは32ビットで閉じた範囲で動作できる。
--64ビット版で提供されるコードは単一のソースから、32ビット版と64ビット版両方をそれぞれコンパイルして作られているため、機能的差異は無い。

**通常のアプリケーション [#le2552e1]
以下に、[[WOW64]]を使用する際の注意点を記述する~
(詳細は[[参考>#j1276255]]の「[[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 
--[[COM]]を経由した32ビットABIのコードと64ビットABIのコードとの相互な呼び出しが禁止されている。

**Webアプリケーション [#u221e8e8]
***IIS [#q59f0ec4]
IISのワーカプロセス(ASPやASP.NETなどのWebアプリケーションがホストされる)も32bit([[WOW64]])をサポートする。

-Windows Server 2003
--TechNet > Windows Server 2003 > IIS 6.0 でアプリケーションを構成する~
64 ビット Windows で 32 ビット ASP.NET を実行するように IIS を構成する~
http://technet.microsoft.com/ja-jp/library/cc737351(WS.10).aspx~
※ IIS6.0では、同じサーバ上で 32bitアプリケーションと 64bitアプリケーションを同時に実行できない。

-Windows Server 2008
--@IT > 強化されたIIS 7.5(前編)~
http://www.atmarkit.co.jp/fwin2k/winsv2008r2/08iis1/iis1_01.html
--TechNet Blogs > Windows Server 使い倒し塾~
64-bit のみとなった Windows Server 2008 R2 の IIS で 32-bit ASP アプリが動くか?~
http://blogs.technet.com/b/windowsserverjp/archive/2009/06/02/3248608.aspx

***IIS Express [#b1ff99e8]
IIS Expressを64bitで動作させることも可能。

+Visual Studioのメニューから[ツール] - [オプション]を開く
+[プロジェクトおよびソリューション] - [Web プロジェクト]を開く
+[Web サイトおよびプロジェクト用 IIS Express の64ビットバージョンを使用]のチェックをONにする

-参考
--IIS Expressを64bitモードで動かす - xin9le.net~
http://blog.xin9le.net/entry/2014/05/07/220837
--Visual Studio Express 2015 for Webで64bit開発 - Qiita~
https://qiita.com/rsuzuki/items/b1b592a04dd0bc4a7210
--Visual Studio で 64ビット版のASP.NET を実行すると~
「ファイルまたはアセンブリ、またはその依存関係の1つが読み込めませんでした。~
間違ったフォーマットのプログラムを読み込もうとしました。」~
エラーが発生する | Visual Studioの使い方 Tips~
https://www.ipentec.com/document/document.aspx?page=visual-studio-2015-asp-net-runtime-error-in-64bit

***レガシーASP [#yf25fbd1]
なお、レガシーASPは、32bit([[WOW64]])もサポートする。~
ただし、殆どの場合は、使用する[[COM]]が 「32bitのVB COM」で開発されているので、~
[[WOW64]]上で32bitアプリケーションとして動作させることとなる。~
([[COM]]を経由した32ビットABIのコードと64ビットABIのコードは相互運用できない。)

-Internet Information Services (IIS) TechCenter~
ダウンロード > インターネット Web サーバー構築ガイドライン~
インターネット Web サーバー構築ガイドライン (ドラフト版)~
http://download.microsoft.com/download/8/F/3/8F3E42CB-5E5A-4BC5-8549-5F408389469F/InternetWebServerGuideline_chapter6_draft.pdf
--第 6 章 アプリケーションを実行環境を設定しよう~
>ASP は IIS の機能の一部として、IIS 7.5 の 32ビット、64ビットのどちらでも正式にサポートされています。 ~
しかしながら、IIS 7 は ASP が当初実行環境として想定していた IIS 4、IIS 5.x と構造も実装も大きく異なり、~
また Windows OS 自体も異なるため、 以前のバージョンの IIS で動作している ASP アプリケーションを、~
IIS 7 に移行する際には、充分かつ、入念なテストを行っていただく必要があります。 ASP アプリケーションの場合、~
.asp ページそのものの互換性は高いのですが、呼び出しているコンポーネントや部品の新環境への対応状況を必ず確認しましょう。

***[[ASP.NET>#q5c87f74]] [#p09391d5]

*VC++ [#n69fa8e6]
**データモデル [#n739b60d]
最も大きな問題は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|ポインタ|処理系|h
|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|?|

詳しくは、下記の[[参考>#j1276255]]を参照。

**64bit COM [#e75c3b22]
-必要に応じて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に変更されています(詳しくは[[下記>#d0772652]]参照)。

*.NET、ASP.NET [#q5c87f74]
-テクニカルドキュメント > .NET 開発 > 技術資料~
32 ビット マネージ コードを 64 ビットに移行する~
http://msdn.microsoft.com/ja-jp/library/ms973190.aspx

以下、.NETのアプリケーションの64bit対応のポイントについて説明する。

**100%タイプ セーフな場合 [#zbba0fc9]
100%タイプ セーフなマネージ コードであれば、そのまま移行可能。

-100%タイプ セーフとは?
--DLL(platform)呼び出し、COM呼び出しをしていないこと。
--/clr:safeオプションでコンパイルされており、低レベルな処理の実行が許可されていないこと。
---ポインタの宣言と処理
---ポインタと整数型の変換
---変数のアドレス取得

**100%タイプ セーフでない場合 [#s6e00db1]
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) [#d1bfc4b5]
-コンパイル オプション(構成の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 を確認する。 

***既定値 [#d0772652]
-VS2010~
EXE を作るプロジェクトのデフォルトが Any CPU から x86 に変更されている。
--EXE を作るプロジェクトのデフォルトが Any CPU から x86 に変わった理由 - または Any CPU の本当の意味~
http://d.hatena.ne.jp/siokoshou/20091102/p1~
>以下の理由で、EXE を作るプロジェクトのデフォルトが Any CPU から x86 に変更されています。

---アーキテクチャ中立のAnyCPU EXE は通常、価値よりもトラブルのほうが多くコスト高。
---32ビットはいずれにしろより速い傾向がある。
---いくつかの機能が64ビットでは利用できない。

-VS2012以降
--しかし、VS2012以降では、再び、デフォルトはAny CPUに戻っている。
--恐らく、製品以外の用途での利用が多く、ソレには、Any CPUが適していたのだと思う。
--また、ODP.NET Managed Driverなどでも、Any CPUの利用が一般的になってきている。

*参考 [#j1276255]
**WOW64 [#sbb278d4]

-WOW64 - Wikipedia~
https://ja.wikipedia.org/wiki/WOW64

***Microsoft [#za43d8bd]
-Microsoft:サポート64 ビット版の Windows Server 2003 と Windows XP での 32 ビット プログラムの互換性について~
http://support.microsoft.com/kb/896456/ja

-Windows ハードウェア デベロッパー センター:WOW64 のベスト プラクティス~
http://msdn.microsoft.com/ja-jp/windows/hardware/gg463051
--ファイル システム リダイレクトはスレッド単位であるため、リダイレクトの無効化が必要なオペレーションは別スレッドに分離する。
--タスクの実行後、できるだけ速やかにリダイレクトを再度有効化する。
--64 ビット プロセスを 32 ビット バージョンのプロセスと同時にインストールする場合は、相互運用性に注意する。
--ソケット、パイプ、RPC、および COM といったプロセス間コミュニケーションを使用する場合は、データの処理におけるビット幅別の対応状況をチェックする。
--32 ビット プロセスから64 ビット プロセスへのアクセスを避ける。

***その他 [#jdc8cd4c]
-ASCII.jp:32bitアプリを64bit Windows 7で動かす「WOW64」~
http://ascii.jp/elem/000/000/480/480200/
-@IT:Win32アプリケーションを実行するWOW64~
http://www.atmarkit.co.jp/fwin2k/special/win64_02/win64_02_01.html

**移行 [#ud78118d]
***MSDN [#w7fc8d1a]
-Visual Studio ドキュメント > Visual C++~
--Visual C++ による 64 ビット プログラミング~
http://msdn.microsoft.com/ja-jp/library/h2k70f3s.aspx
---方法 : Visual C++ プロジェクトを 64 ビット プラットフォーム用に設定する~
http://msdn.microsoft.com/ja-jp/library/9yb4317s.aspx
---方法 : 64 ビットの Visual C++ ツールセットをコマンド ラインから有効にする~
http://msdn.microsoft.com/ja-jp/library/x4d2c09s.aspx
---Visual C++ の 64 ビットへの移行に関する一般的な問題~
http://msdn.microsoft.com/ja-jp/library/3b2e7499.aspx
---Itanium ソフトウェア規則~
http://msdn.microsoft.com/ja-jp/library/ms235233.aspx
---x64 ソフトウェア規約~
http://msdn.microsoft.com/ja-jp/library/7kcdt6fy.aspx

-Windows 開発 > 64 ビット Windows プログラミング ガイド
--開発ガイド > 64 ビット Windows プログラミング ガイド~
http://msdn.microsoft.com/ja-jp/library/bb427430.aspx
---64 ビット版 Windows での使用に向けた準備~
http://msdn.microsoft.com/ja-jp/library/aa384198.aspx
---64 ビット互換インターフェイスの設計~
http://msdn.microsoft.com/ja-jp/library/aa384167.aspx
---32 ビット アプリケーションの実行~
http://msdn.microsoft.com/ja-jp/library/aa384249.aspx
---移行に関するヒント~
http://msdn.microsoft.com/ja-jp/library/aa384214.aspx~
● 移植に関する一般的なガイドライン~
● 64 ビット値の格納~
● 一般的なコンパイラ エラー~
● その他の考慮事項~

-テクニカルドキュメント > .NET 開発 > 技術資料
--32 ビット マネージ コードを 64 ビットに移行する~
http://msdn.microsoft.com/ja-jp/library/ms973190.aspx

-MSDN Blogs > とあるコンサルタントのつぶやき
--All Tags > 64bit~
http://blogs.msdn.com/b/nakama/archive/tags/64bit/
---.NET Framework アプリケーションの 64bit 対応~
http://blogs.msdn.com/b/nakama/archive/2008/10/30/net-framework-64bit.aspx
---Part 1. 64 ビット Windows OS の基本知識~
http://blogs.msdn.com/b/nakama/archive/2008/10/30/part-1-64-windows-os.aspx
---Part 2. .NET Framework 2.0 アプリケーションの 64 ビット対応~
http://blogs.msdn.com/b/nakama/archive/2008/11/06/part-2-net-framework-2-0-64.aspx
---Part 3. ASP.NET 2.0 Web アプリケーションの 64 ビット対応~
http://blogs.msdn.com/b/nakama/archive/2008/11/13/part-3-asp-net-2-0-web-64.aspx

-ITmedia エンタープライズ
--64ビットコンピューティング最前線
---64ビットプログラミングのポイント(1/3)~
http://www.itmedia.co.jp/enterprise/articles/0506/14/news003.html
---64ビットプログラミングのポイント(2/3)~
http://www.itmedia.co.jp/enterprise/articles/0506/14/news003_2.html
---64ビットプログラミングのポイント(3/3)~
http://www.itmedia.co.jp/enterprise/articles/0506/14/news003_3.html~
● ポインタをint型やlong型変数に代入しない~
● long型とint型が混在した計算に気をつける~
● long型を4バイトデータに使わない~
● 定数の補数表現に気をつける~
● printf関数のフォーマットに注意する~
● アライメント(Alignment)、構造体のサイズなど~

--64ビットコンピューティング最前線:64ビットになると何が変わる?
---64ビットプログラミングのデータモデル(1/2)~
http://www.itmedia.co.jp/enterprise/articles/0506/13/news006.html
---64ビットプログラミングのデータモデル(2/2)~
http://www.itmedia.co.jp/enterprise/articles/0506/13/news006_2.html

----
Tags: [[:プログラミング]], [[:移行]], [[:.NET開発]]

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS