Visual Studio 2005 を使用して Windows Vista で gtkmm を使用して Gtk アプリケーションを開発しています。アプリケーションは開発マシンでは問題なく動作しますが、Windows XP マシン (Service Pack 2 と 3 の両方) で実行した後にクラッシュ レポートを受け取りました。http://live.gnome.org/gtkmm/MSWindowsに記載されているディレクトリ構造でアプリを配布しましたが、これまでのところ問題はありませんでした。
クラッシュは、Windows がエラーを報告するかどうかを尋ねる以外、エラー メッセージを表示しません。
この問題を解決するために、異なるバージョンの gtkmm (最新の安定バージョン gtkmm-win32-devel-2.16.0-4 と古いバージョン gtkmm-win32-devel-2.10.11-1) に対してプログラムをコンパイルしようとしました。しかし、問題は解決しませんでした。
Gtk::DrawingArea の on_expose_event 内で window->create_cairo_context() を呼び出して問題を突き止めました。この呼び出しをコメントアウトすると、問題はなくなります。そこで、次の最小限のプログラムを作成しましたが、それでもクラッシュします。
#include <gtkmm.h>
#include <iostream>
class MyWindow : public Gtk::Window {
bool on_expose_event(GdkEventExpose* event) {
std::cout << "expose" << std::endl;
Glib::RefPtr<Gdk::Window> window = get_window();
if(window) {
std::cout << "win" << std::endl;
std::cout << "Get cairo" << std::endl;
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
std::cout << "Get cairo done" << std::endl;
} else {
std::cout << "no win" << std::endl;
}
return true;
}
};
int main (int argc, char *argv[]) {
Gtk::Main m(argc,argv);
MyWindow w;
m.run(w);
return 0;
}
この最小限のアプリは問題なく実行してウィンドウを表示できますが、ウィンドウを画面の制限外に移動したり、十分な回数最小化/最大化したりすると (on_expose_event の呼び出しがトリガーされます)、最終的にクラッシュします。最初はクラッシュしない場合もありますが、アプリを再起動し、上記のように on_expose_event を複数回呼び出すとクラッシュします。私が気づいたことの 1 つは、「Get cairo done」を印刷した後にアプリがクラッシュすることです。create_cairo_context の呼び出しをコメント アウトすると、問題が解消されるので、この行に何か問題があると確信できます。
このエラーは、クリーン インストールされた Windows XP マシンで発生します。Windows XP を搭載した同僚のノートブックで両方のアプリ (オリジナルと最小) をテストしましたが、クラッシュしませんでした。私たちのコンピューターでは利用可能/最新の依存関係があると思いますが、アプリケーションがクラッシュするコンピューターには依存関係がありません。問題のあるマシンの 1 つに DirectX を更新し、Visual Studio C++ 2005 Redistributable をインストールしましたが、問題は解決しません。
DrawingArea にグラフを描画する元のアプリも、必ずしも最初にクラッシュするとは限りません。再起動後の初回は正常に動作する場合がありますが、2 回目は失敗する可能性が高くなります。
問題が解決するかどうかを確認するために、MinGW でコンパイルしてテストすることを考えています。また、デバッグ バージョンをコンパイルして、デバッガーを使用してみます。Dependency Walkerによると、libcairo-2.dllがこのdllに依存していることを見て、gdi32.dllのバージョンに何か関係があるのではないかと疑っていますが、今のところそれは単なる推測です. それ以外は、私はアイデアがありません。
とりあえず、これらのアイデアを試してみます。うまくいけば、誰かがより多くの提案をしたり、上記のコードで何が起こっているのかを知っています.