You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:32:25