#navi_header|読書メモ| "APIで学ぶWindows徹底理解"のPart6 - Part10までの読書メモです。 この読書メモのスタンス、およびサンプルコードの入手については以下を参照して下さい。 [[652]] #more|| ---- * 【Part 06】Windowsのメモリー管理を理解する Windowsのメモリー管理機能について詳しく知りたい: "MSDN Library" > "Windows Development" > "System Services" > "Memory Management" "Windows 開発チームからのドライバー開発に関する覚え書き" の "Windows のメモリ管理": http://www.microsoft.com/japan/whdc/driver/foundation/DevNotes.mspx ** サンプル解説("Part06_Memory\"フォルダ) : 06_01.cpp : #block||> 本書83p, リスト4のVC++移植版。 コンパイル方法: cl 06_01.cpp ..\VirtualWalk.obj ..\PrintErrorMsg.obj VirtualAlloc()を使ってページを予約/コミットするサンプル。VirtualAlloc()呼び出し前後でのメモリ利用状況を表示し、実際に状態が変わっていることを確認出来る。 ||< : 06_02.cpp : #block||> 本書85p, リスト9のVC++移植版。 コンパイル方法: cl 06_02.cpp ..\VirtualWalk.obj ..\PrintErrorMsg.obj HeapAlloc()を使ってメモリを割り当てるサンプル。何回かのHeapAlloc()に伴い、Heapの予約/コミット状況やサイズを確認できる。 ||< * 【Part 07】Windowsのプロセスとスレッドを学ぶ : プロセスとスレッドについて詳しく知りたい : "MSDN Library" > "Windows Development" > "System Services" > "DLLs, Processes, and Threads" > "Processes and Threads" ** サンプル解説("Part07_Process_Thread\"フォルダ) : 07_01.cpp : #block||> 本書88p, リスト1のVC++移植版+簡略化版。 コンパイル方法: cl 07_01.cpp ..\PrintErrorMsg.obj CreateProcess()でnotepad.exe(メモ帳)を起動するサンプル。本書の方ではウインドウを表示してメニューをクリックした時に起動するが、こちらの読書メモのサンプルでは単にmain()の中でCreateProcess()を実行して終わりと、周辺コードをバッサリと削りシンプルにしている。 ||< : 07_02.cpp : #block||> 本書90p, リスト5のVC++移植版+簡略化版。 コンパイル方法: cl 07_02.cpp ..\PrintErrorMsg.obj 07_01.cppに手を加え、WaitForSingleObject()とGetExitCodeProcess()を使ってプロセスの終了コードを表示するようにした。 ||< : 07_03.cpp : #block||> 本書93p, リスト9, 10のVC++移植版+簡略化版。 コンパイル方法: cl /MT 07_03.cpp ..\PrintErrorMsg.obj "_beginthreadex()"で複数スレッドを起動するサンプル。スレッドの中身は、単にカウントアップを表示するだけのコードに簡略化している。 ||< * 【Part 08】複数スレッドの間で同期をとる : 同期全般 : "MSDN Library" > "Windows Development" > "System Services" > "DLLs, Processes, and Threads" > "Synchronization" > "About Synchronization" : クリティカルセクション(Critical Section)を使った同期について詳しく知りたい : ... > "Critical Section Objects" : セマフォ(Semaphore)を使った同期について詳しく知りたい : ... > "Synchronization Objects" > "Semaphore Objects" : ミューテックス(Mutex)を使った同期について詳しく知りたい : ... > "Synchronization Objects" > "Mutex Objects" : イベント(Event)を使った同期について詳しく知りたい : ... > "Synchronization Objects" > "Event Objects" ** サンプル解説("Part08_Thread_Sync\"フォルダ) : 08_01.cpp : #block||> 本書95p, リスト1のVC++移植版+簡略化版。 コンパイル方法: cl /MT 08_01.cpp ..\PrintErrorMsg.obj グローバル変数を10カウントアップする関数をスレッドとして5つ立ち上げる。5秒後(=全スレッドが10のカウントアップ完了後)、最終的なグローバル変数の値を表示するが、特に同期や排他処理を組み込んでいない為、10(カウントアップ) x 5(スレッド数) = 50 にならない事を確認出来る。 ||< : 08_02.cpp : #block||> 本書96p, リスト2のVC++移植版+簡略化版。 コンパイル方法: cl /MT 08_02.cpp ..\PrintErrorMsg.obj 08_01.cppでのカウントアップ部分をクリティカルセクション(CriticalSection)で囲んだ。今度は各スレッド間で排他的にカウントアップされるようになり、最終的なグローバル変数は50となる。 ||< : 08_03.cpp : #block||> 本書99p, リスト3のVC++移植版+簡略化版。 コンパイル方法: cl /MT 08_03.cpp ..\PrintErrorMsg.obj 08_01.cppでのカウントアップ部分をミューテックス(Mutex)を使って同期するようにした。08_02.cppと同様、最終的なグローバル変数は50となる。 ||< * 【Part 09】作ってわかるDLLの動作原理 : DLLについて詳しく知りたい : "MSDN Library" > "Windows Development" > "System Services" > "DLLs, Processes, and Threads" > "Dynamic-Link Libraries" ** サンプル解説("Part09_DLL\"フォルダ) こちらの読書メモサンプルコードは、書籍とは大きく構成を変更したほぼオリジナルとなっている。 + 09_01_dllstub.c, 09_01_en.rc, 09_01_ja.rc を使ってリソースを格納しただけのDLLを作成する。どちらのrcファイルをリンクするかにより、英語用・日本語用のDLLをそれぞれ作成出来る。 + 09_01_main.cをコンパイルする。上で作成した英語用・日本語用を適当にリネームするなどして、どちらのDLLをロードするかに応じて文字列リソースの英語・日本語が切り替わることを確認する。 : 09_01_dllstub.c, 09_01_en.rc, 09_01_ja.rc : #block||> コンパイル方法: rc 09_01_en.rc rc 09_01_ja.rc cl /c 09_01_dllstub.c link /OUT:09_01_en.dll /DLL 09_01_dllstub.obj 09_01_en.res link /OUT:09_01_ja.dll /DLL 09_01_dllstub.obj 09_01_ja.res 09_01_en.dllが英語用、09_01_ja.dllが日本語用となる。 ||< : 09_01_main.c : #block||> コンパイル方法: cl 09_01_main.c user32.lib ..\PrintErrorMsg.obj DLLをロードし、文字列リソースを取得してprintf()で表示するサンプル。ロードするDLL名は"09_01.dll"にしている。上で作成した09_01_en.dll, 09_01_ja.dllをそれぞれ"09_01.dll"にリネームし、日本語・英語が切り替わることを確認出来る。 なおロード方法はLoadLibrary()を用いた明示的なロードを使っている(=インポートライブラリは使わない)。 ||< * 【Part 10】複数プロセスでデータを共有する : メモリマップドファイル(Memory Mapped File)や共有メモリ(Shared Memory)について知りたい : "MSDN Library" > "Windows Development" > "System Services" > "Memory Management" > "About Memory Management" > "File Mapping" : COPYDATASTRUCT構造体とWM_COPYDATAメッセージを使ったプロセス間データコピーについて知りたい : "MSDN Library" > "Windows Development" > "Windows Application UI Development" > "Windows User Interface" > "Data Exchange" > "Data Copy" ** サンプル解説("Part10_Shared_Memory\"フォルダ) : 10_01_fileinit.cpp, 10_01_fileread.cpp, 10_01_filewrite.cpp : #block||> 本書114p, リスト6, 115p, リスト7のVC++移植版+簡略化版。 コンパイル方法: cl 10_01_fileinit.cpp user32.lib ..\PrintErrorMsg.obj cl 10_01_fileread.cpp user32.lib ..\PrintErrorMsg.obj cl 10_01_filewrite.cpp user32.lib ..\PrintErrorMsg.obj 動かし方: + 10_01_fileinit.exeを実行し、共有メモリ用のデータファイルを作成する。 + コマンドプロンプトを2つ立ち上げる。 + まずコマンドプロンプトの片方で10_01_filewrite.exeを実行する。 + すぐにもう片方のコマンドプロンプトで10_01_fileread.exeを実行する。 10_01_filewriteでは、共有メモリに20回、ランダムデータを書き込む。10_01_filereadでは共有メモリから20回、データを読み込み表示する。両方が終了した時点でのデータファイルの内容と照らし合わせることで、FileMappingによるプロセス間の共有メモリ機能を確認出来る。 ||< : 10_02_read.cpp, 10_02_write.cpp : #block||> 本書114p, リスト6, 115p, リスト7のVC++移植版+簡略化版+実体ファイル無し版。 コンパイル方法: cl 10_02_read.cpp user32.lib ..\PrintErrorMsg.obj cl 10_02_write.cpp user32.lib ..\PrintErrorMsg.obj 動かし方: + コマンドプロンプトを2つ立ち上げる。 + まずコマンドプロンプトの片方で10_02_write.exeを実行する。 + すぐにもう片方のコマンドプロンプトで10_02_read.exeを実行する。 10_02系では、実際の物理ファイルを持たない共有メモリ機能を確認出来る。ランダムデータの読み・書きプロセスに分離しているのは10_01系と同じ。CreateFileMapping()にINVALID_HANDLE_VALUEをファイルハンドルとして渡すことで、物理ファイルにマッピングされない純粋にメモリ上だけに存在する共有メモリを使っている。 ||< : 10_03_recv.cpp, 10_03_send.cpp : #block||> 本書116p, リスト9, 117p, リスト10のVC++移植版+簡略化版。 コンパイル方法: cl 10_03_recv.cpp user32.lib cl 10_03_send.cpp user32.lib 動かし方: + 10_03_recv.exe と 10_03_send.exe を実行する。 + 10_03_send のウインドウ内を左 or 右クリックすると、10_03_recv のウインドウにメッセージボックスが表示され、WM_COPYDATA経由で渡されたメッセージが表示される。 ||< #navi_footer|読書メモ|