GLib-GObject-CRITICAL ... 断言'quark > 0'失败。

5

我对Gtk编程比较新。我正在使用Gtkmm库为我的应用程序编写一个简单的GUI界面。

GUI界面是一个更大的应用程序的一部分,实际上编译成了两个独立的可执行文件,但我认为这与本问题无关,因为这个问题只涉及其中一个可执行文件。

无论如何,我在client.cpp中有以下代码:

#include "client.hpp"

int main() {
    auto builder = Gtk::Builder::create();
}

在 client.hpp 文件中,我只包含了 iostream、glibmm.h 和各种 gtkmm 控件头文件,以及 gtkmm/builder.h。
我的 Makefile 一团糟,但是这是它的内容:
CXXFLAGS= -std=c++14 -g
LDFLAGS=-lgmp -pthread $(shell pkg-config -libs gtkmm-3.0)
SERVER_EXE=server
CLIENT_EXE=client
CXX=g++
DIST_DIR=.
BUILD_DIR=./build

SERVER_CXXFLAGS=
CLIENT_CXXFLAGS=$(shell pkg-config --cflags gtkmm-3.0)

INCLUDE_DIRS=./include
INCLUDE_PARAMS=$(foreach d, $(INCLUDE_DIRS), -I$d)

SERVER_OBJECTS=rsa.o server_entry.o server.o
SERVER_OBJECT_PATHS=$(foreach o, $(SERVER_OBJECTS), $(BUILD_DIR)/$o)

CLIENT_OBJECTS=resources.o client.o
CLIENT_OBJECT_PATHS=$(foreach o, $(CLIENT_OBJECTS), $(BUILD_DIR)/$o)

all: $(SERVER_OBJECT_PATHS) $(CLIENT_OBJECT_PATHS)
    mkdir -p $(DIST_DIR)
    $(CXX) $(CLIENT_OBJECT_PATHS) -o $(DIST_DIR)/$(CLIENT_EXE) $(LDFLAGS)
    $(CXX) $(SERVER_OBJECT_PATHS) -o $(DIST_DIR)/$(SERVER_EXE) $(LDFLAGS)

clean:
    rm -rf $(BUILD_DIR)
    rm $(DIST_DIR)/$(CLIENT_EXE) $(DIST_DIR)/$(SERVER_EXE)

$(BUILD_DIR)/%.o: %.cpp
    mkdir -p $(BUILD_DIR)
    $(CXX) -c $< $(INCLUDE_PARAMS) -o $@ $(CXXFLAGS) $(SERVER_CXXFLAGS) $(CLIENT_CXXFLAGS)

resources.cpp:
    glib-compile-resources --target=resources.cpp --generate-source windows.gresource.xml

我意识到这可能是一大堆信息,因为它实际上构建了两个可执行文件,但是对于这个问题,您可以安全地只考虑与客户端程序相关的内容。
底部的规则用于将我制作的glade文件转换为可以链接到我的client.cpp文件的c++文件。
无论如何,当我运行程序时,我会得到以下输出:
(process:16593): GLib-GObject-CRITICAL **: 23:15:27.886: g_object_set_qdata_full: assertion 'quark > 0' failed

我完全不知道这个错误信息可能意味着什么。由于我对这个库的经验不是很丰富,我不确定该怎么理解它。我还尝试在我的代码后面添加一行来从资源中加载构建器小部件,但这导致了更多的关键错误和段错误。我希望如果我能修复这个第一个错误,其他所有问题都会迎刃而解。有什么想法吗?谢谢!更新1:当我将client.cpp的源代码更改为here提供的源代码时,它完美地工作!所以这很奇怪...

在环境中设置G_DEBUG=fatal-warnings,并使用gdb运行您的程序,查看回溯信息(或在此处发布)。请参阅https://developer.gnome.org/glib/stable/glib-running.html#G-DEBUG:CAPS。 - Philip Withnall
@PhilipWithnall 感谢您的回复。我的理解是,我需要输入 G_DEBUG=fatal-warnings 然后输入 gdb client,之后在 gdb 运行时输入 'run',然后输入 'where',这样就可以了吗?但当我这样做时,它只会显示“无堆栈”。 - Jacob Garby
是的,您可以在一个命令中输入所有内容(G_DEBUG=fatal-warnings gdb ./client),或者先使用export G_DEBUG=fatal-warnings,然后再输入gdb ./client。为了获得回溯信息,您需要安装GLib的调试符号,并使用-g -O1编译您的应用程序。 - Philip Withnall
1个回答

8
我很确定GLibMM必须在您调用任何Glib/Gtk函数之前使用进行初始化。 Gtk::Application::create()会为您完成此操作,这就是为什么示例可以正常工作的原因。

1
请注意,有一个小错误,create应该是小写:Gtk::Application::create(argc, argv); - fgiraldeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接