创建GLib可派生类型失败,调用MY_ITEM_CLASS触发GLib-GObject临界错误
问题解决:GObject派生类型调用虚方法时的临界错误
错误原因
你误用了GObject的类型转换宏:MY_ITEM_CLASS()是用来将类结构指针(如GObjectClass)转换为MyItemClass类型的宏,而非从实例对象中获取类结构的工具。直接把实例指针result传入该宏,会导致类型不匹配,触发GLib的临界错误。
正确做法是使用MY_ITEM_GET_CLASS()宏——这是G_DECLARE_DERIVABLE_TYPE自动生成的宏,专门用于从实例对象中提取对应的类结构。
修改后的代码
只需调整main函数中调用虚方法的行:
#include <glib-object.h> #include <iostream> typedef struct _MyItem MyItem; #define MY_TYPE_ITEM (my_item_get_type()) G_DECLARE_DERIVABLE_TYPE(MyItem, my_item, MY, ITEM, GObject) struct _MyItemClass { GObjectClass parent; void (*print)(MyItem* self); }; typedef struct { const char* name; } MyItemPrivate; auto static my_item_init (MyItem *object) -> void; auto static my_item_class_init (MyItemClass* klass) -> void; G_DEFINE_TYPE_WITH_PRIVATE (MyItem, my_item, G_TYPE_OBJECT) auto static item__print(MyItem* self) -> void { auto priv = (MyItemPrivate*)my_item_get_instance_private(self); std::cout << (priv->name?priv->name:"unnamed") << std::endl; } auto static my_item_init (MyItem *object) -> void { auto priv = (MyItemPrivate*)my_item_get_instance_private(object); priv->name = "This is my name"; } auto static my_item_class_init (MyItemClass* klass) -> void { GObjectClass *object_class = G_OBJECT_CLASS(klass); klass->print = item__print; } auto main() -> int { auto result = (MyItem*)g_object_new(MY_TYPE_ITEM, nullptr); // 替换MY_ITEM_CLASS为MY_ITEM_GET_CLASS MY_ITEM_GET_CLASS(result)->print(result); g_object_unref(result); return 0; }
关键宏的区别
MY_ITEM_CLASS(class_ptr):用于类型安全地将父类的类结构指针转换为当前类的类结构指针,比如G_OBJECT_CLASS(klass)就是类似的反向转换操作。MY_ITEM_GET_CLASS(instance):从实例对象中提取对应的类结构指针并做类型检查,是获取实例类结构的标准方式。
编译运行修改后的代码,临界错误会消失,程序将正常输出This is my name。
内容的提问来源于stack exchange,提问作者Lothar
相关产品推荐
相关产品推荐

