前書き 「プロセスIDならわかるけど、ウィンドウハンドルはわからないなー」なんていう状況、よくありますよね? 僕は先ほど初めてそのような状況に出くわしましたけど。 流れ トップレベルウィンドウを列挙 各ウィンドウのプロセスIDを調べる 目当てのプロセスIDが見つかったら、そのウィンドウのウィンドウハンドルを返す ソース // // プロセスIDからウィンドウハンドルを取得する。 // トップレベルウィンドウを列挙して、プロセスIDが一致するやつのHWNDを返す。 // 同じプロセスIDでトップレベルウィンドウが複数個あった場合は // どうなっても知らない。 // HWND GetWindowHandle( // 戻り値: 成功 望みのHWND / 失敗 NULL const DWORD TargetID) // プロセスID { HWND hWnd = GetTopWindow(NULL
VirtualAlloc 系ではページ単位でメモリを操作する。このため(アクセス権の設定の面で)柔軟であるが小さなメモリブロックの割り当てに向かない。一 方 HeapAlloc 系では、予めある程度 の仮想メモリ 領域を予約しておき、プログラムから要求がされ次第、その予約された領域からメモリを切り出してきてメモリブロックを確保する。小さなメモリブロックを多 数割り当てるにはこちらの方法のほうが効率が良い。Windows のヒープマネージャはこのような動作を実現できるように、プログラムと仮想メモリマネージャの間に入りメモリ割り当てを高速に行う。 DEPWindows XP SP2 から HeapAlloc によって割り当てられるメモリ (ページ) の属性が変わり、割り当てられるメモリブロックでは実行可能ではなくなった。もし実行しようとするとアクセス違反が発生する。このテクノロジを Data
会社で開発しているアプリケーションで、プログラムの[閉じる]ボタンを押しても数秒間固まったままになるものがあった。別に、WaitForXXXObject(s)しているわけでもないし、そんなに重い処理をしている訳でもない。理由がわからないまましばらく放置していたのだが、今日になってやっと原因が判明した。たった一つのdeleteに数百ミリ秒のオーダーで時間が消費されていた。別にデストラクタがあるわけでもないクラスのインスタンスでだ。 いろいろと調べたところ、ヒープの断片化が激しいらしい。かといって、断片化を防ぐコードを書くのもなかなか難しい。いくつかのインスタンスには、無理矢理compact()っていう関数を導入してみて、適宜、メモリの再確保によって断片化を押さえるようにしたものの、全体的には、あんまり改善できず。 仕方がないので、ちょっとだけ調べてみると、Windows XP以降では、low
第2回が来てしまいました。第1回から2年ぐらいでしょうか? 私、MFCで制御系のアプリをかかされる羽目になりその際のテクニックなどをかいときます。 MFCでスレッドを使う MFCでスレッドを使うには AfxBeginThread を利用してCWinThread型のオブジェクトを作るわけですが、通信アプリとか制御系のアプリの場合しばしば「スレッドの終了を待ちたい!」と言う要求が発生します。で、そのやり方です。 class CHogeHoge { public: CHogeHoge(); // コンストラクタ ~CHogeHoge(); // デストラクタ void Start(void); // スレッドの開始 void Stop(void); // スレッドの終了 protected: static UINT ThreadEntry(LPVOID pParam); // スレッド開始位置
戻る 32ビットアプリケーションを作成するための環境が整い,16ビット アプリケーションを新規に作成することは少なくなってきているのではないかと 思われます.16ビットアプリケーションと異なり,32ビットでは完全な (プリエンティブな)マルチスレッド・マルチタスクでプロセスが実行できるように なっています. しかし,最近スレッドの使い方を誤ることによるトラブルをよく見掛け ます.スレッドを使い方を間違えるとシステムのパフォーマンスを低下させたり, システムリソースを不必要に消費させてしまいます.また,各スレッドで共有する システムリソースを,いずれかのスレッドが勝手に破棄したり,スレッドが何かの処理 を行っている途中でプロセスが終了してしまうと何が起こるか分かりません. そこで,基本的なスレッドの扱いについてまとめてみたいと思います. 19-1 スレッドとは いまさらスレッドを説明すること
「スレッド」、それは「処理単位」のことです。 実行されるアプリケーションひとつひとつを「プロセス」と呼びます。プロセスは最初にスレッドをひとつ持ちます。ウィンドウをいくつも作り、ウィンドウプロシージャが複数あっても、スレッドが同じならメッセージはひとつひとつ処理されます。 この問題はユーザーインターフェイスを著しく損ないます。例えばウィンドウのデバイスコンテキストに複雑な描画をするとします。描画に時間が掛かるため、ツールボックスに「停止」ボタンを作製しました。さて、いざ描画をシングルスレッド、つまりごく普通に処理した場合、最悪、描画中にはこのボタンを押すことすら不可能になります。 この問題を解決する方法が、マルチスレッドです。新たにスレッドを作製し、そのスレッドの中でメモリデバイスコンテキストへの描画をさせ、最後にウィンドウデバイスコンテキストへとコピーしてスレッドを終了させる、という方法
akusanのブログゲーム、プログラミングなどなど種々雑多に興味あるものをのせております。プログラミングはたまにコード自体を載せております。 最近、仕事でメモリリークの解析をしていてかなり大変な感じに・・・。 メモリリークは本当に発見するのが難しい・・・。 しかも、諸事情により実行できないところがきついですね・・・。 ソースコードのみからやっているので・・・。 C、C++はメモリリークしやすいのはしょうがないことですが、 メモリリークをしないように確実にnewしたらdeleteをするのが重要ですよね~。 あとは、ライブラリで確実にInitializeしたら、terminateとかそういった操作が必要ですね。 メモリリークの解析手法の一つとして、Visual Studioならば、以下の関数を使うとツールを 必要とせずにメモリリークの検出ができます。 _CrtDumpMemoryLeaks()
解説 1.まとめ Visual C++ 2005 (Visual Studio 2005) を使用した、「メモリリークのメモリ確保場所の特定」に関してまとめます。 より正しくは、Visual C++ 2005 (Visual Studio 2005) の出力ウィンドウに「検出したメモリリークのメモリ確保場所のソースファイル名、行番号をダンプする方法」に関してまとめます。 (「メモリリークを検出するには」も同時に実施する必要があります) 「メモリ確保関数をデバッグバージョンの関数に置き換える定義」をソースファイルの先頭に記述すると、検出したメモリリークのメモリ確保場所のソースファイル名、行番号が出力ウィンドウにダンプされるようになります。 ただし、この方法による「メモリリークのメモリ確保場所を特定」は、デバッグバージョンの場合(プリプロセッサの定義で _DEBUG が定義されている場合)にし
本の虫: いまだに変な宗教が流行っているを書いたところ、どうもこのへんの情報は、あまり知られていないようであるので、できるだけ分かりやすく解説することにした。 Cの標準ライブラリは、恐ろしく古いライブラリである。その設計は、マルチプロセッサ(コア)上で動作するマルチスレッドが当然の現代では、あまりよろしくない。 たとえば、strtokという関数がある。この関数は、引数として渡された文字列を、内部のバッファにコピーする。次のstrtokの引数には、NULLを渡すことで、そのコピーされたバッファから、次のトークンの場所へのポインターを返すのである。 void f( char const * ptr ) { char const * p1 = strtok( ptr, " " ) ; char const * p2 = strtok( NULL, " " ) ; } しかしもし、strtokが複
マルチスレッド対応OSにおけるプログラム実行の単位のことで、Windowsはマルチスレッドをサポートしています。 プログラム(プロセスとも呼ぶ)の中で複数のスレッドを実行することができ、実行すると(プロセスを実行する)最低1つのスレッドが作成されます。このスレッドを特にプライマリスレッド(primarythread)と呼びます。 マルチスレッドを利用することにより、長時間かかる処理を実行してもプライマリスレッド等に影響を及ぼさない、また同時に複数のスレッドと同期を取りながら処理することが出来ます。 デメリットとしては、終了処理が少々面倒、また同期処理にバグがあるとデッドロックの発生、リソース競合発生の可能性があり、最悪の場合プログラムを強制終了させる必要が発生したり、例外関連のエラー等で処理がストップする可能性があります。
普通の例外 ゼロ徐算やアクセス違反などの低レベルな例外(SE)を取ることができません。クラッシュしてしまいます。 try { throw std::exception("hoge"); } catch (exception capture) { std::cout << capture.what() << std::endl; } catch (...) { std::cout << "Unknown" << std::endl; } finally { ... } _EXCEPTION_POINTERS* info = nullptr; __try { auto hoge = 1 / ZERO; // 0徐算 nullObject->Invoke(); // アクセス違反 } __except(info = GetExceptionInformation(), EXCEPTION_EXE
これらはマクロなので、実際は整数が割り当てられている。 しかし__except()は正か0か負かという判断しかしてないらしいので、実はどんな値でもよい…? とは言え、上記のようなマクロが定義されているんだから、それを指定するべきだろう。 という訳で、__exceptの括弧内に式(MSDNではフィルタ式と称している)を書いて最終的に整数を返すことにより、条件に応じて処理を変更することが出来る。 例えばカンマ演算子を使ったり、独自の別関数(MSDNではフィルタ関数と称している)を呼び出したりすればよい。 _EXCEPTION_POINTERS* info; __try { 処理; } __except (info = GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) { //構造化例外の情報をinfoに入れている。 //カンマ演算子では
プログラムで構造化例外が出た時に、スタックバックトレースを見たくなったのですが、その時に作った簡単な動作検証用コードを載せておきます。 構造化例外が出るコード まずはわざと構造化例外が発生するプログラムを用意します。 一番下のmain関数から始まって、test2関数で構造化例外が発生します。 #include "pch.h" #include <iostream> #include "StackBackTrace.h" void test2() { char *a = nullptr; memcpy(a, "abc", 4); } void test1() { test2(); } void se_translator(unsigned int u, _EXCEPTION_POINTERS *e) { printf_s("In se_translator. cEip = 0x%x\n",
構造化例外から C++ 例外への明示的な変換 前回は構造化例外処理 (SEH) における例外と C++ 例外は異なるものであることを説明しました。 考えてみれば名前からして別物なのですが同じ「例外」ですし、さらに /EHa コンパイラオプションの元では、 SEH も (キャッチできれば) キャッチしますから、混乱するのは当然ともいえます。 今回は SEH が発生したときに、C++ 例外を明示的にスローするための方法を説明します。 _set_se_translator 関数による変換関数の指定 Visual C++ では _set_se_translator 関数 が用意されています。 これに変換関数を渡すと、構造化例外が発生したときにその変換関数が呼び出されるようになります。 そして、変換関数で C++ 例外をスローすればよいのです。 変換関数の型は次の通りです。 typedef void
通常フォームを最前面に持ってくるにはTopMostプロパティを利用します。 ですが、以下のWin-APIを利用しても同じ事が実現出来ます。 SetWindowPos関数 引数などの指定は以下を参照してください。 SetWindowPos関数 http://msdn.microsoft.com/ja-jp/library/cc411206.aspx 別にこの関数を利用しなくてもTopMostで同じ事が出来るので いらないのではと思ったりしますが、SetWindowPos関数は 引数にいろいろ指定できるので、結構便利だったりします。 普段利用する事はないですが、知っておくと役に立つかもしれませんね。 具体的には以下のような事ができます。 Zオーダーの位置を細かく指定できる ウィンドウのサイズを指定できる ウィンドウの位置を指定できる 以下、サンプルです。 using System; using
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く