我正在使用 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 的调用),它最终会崩溃。也有可能是第一次不会crash,但是重启app,触发多次on_expose_event调用后就会crash。我注意到的一件事是应用程序在打印“Get cairo done”后崩溃。当我注释掉对 create_cairo_context 的调用时,问题就消失了,所以我很确定这条线有问题。
该错误发生在全新安装的 Windows XP 机器上。我已经在同事的笔记本上测试了这两个应用程序(原始的和最小的),它也有 Windows XP,但它不会在那里崩溃。我想在我们的计算机中存在一些可用/最新的依赖关系,但在应用程序崩溃的计算机中没有。我已更新 DirectX 并在其中一台有问题的机器上安装了 Visual Studio C++ 2005 Redistributable,但问题仍然存在。
在 DrawingArea 上绘制图形的原始应用程序也不一定第一次崩溃。重新启动后第一次可能工作正常,但第二次更容易失败。
我正在考虑使用 MinGW 进行编译和测试,看看是否能解决问题。我还将尝试编译调试版本并尝试使用调试器。我怀疑 gdi32.dll 的版本可能有问题,根据 Dependency Walker 看到 libcairo-2.dll 依赖于这个 dll,但直到现在这只是一个猜测。除此之外,我没有想法。
我会暂时尝试这些想法。希望有人有更多建议或知道上面的代码发生了什么。