编写C语言GObject类时,是否需自行实现new方法?
问题描述
我正在遵循GObject教程编写自己的第一个GObject类,目前已完成以下代码:
train.h
#pragma once #include <glib-object.h> G_BEGIN_DECLS #define EXAMPLE_TYPE_TRAIN example_train_get_type () G_DECLARE_DERIVABLE_TYPE (ExampleTrain, example_train, EXAMPLE, TRAIN, GObject) struct _ExampleTrainClass { GObjectClass parent_class; void (* get_route) (ExampleTrain *train); }; ExampleTrain *example_train_new (void); G_END_DECLS
train.c
#include "train.h" typedef struct { char *origin; } ExampleTrainPrivate; G_DEFINE_TYPE_WITH_PRIVATE (ExampleTrain, example_train, G_TYPE_OBJECT) static void example_train_class_init (ExampleTrainClass *klass) { } static void example_train_init (ExampleTrain *self) { ExampleTrainPrivate *priv = example_train_get_instance_private (self); }
目前代码可编译,但尝试在main.c中调用example_train_new ()实例化类时,出现以下链接错误:
[1/2] Compiling C object src/gobject-inheritance.p/main.c.o ../../../../../gobject-inheritance/src/main.c: In function ‘main’: ../../../../../gobject-inheritance/src/main.c:13:17: warning: unused variable ‘train_one’ [-Wunused-variable] 13 | ExampleTrain *train_one = example_train_new (); | ^~~~~~~~~ [2/2] Linking target src/gobject-inheritance FAILED: src/gobject-inheritance cc -o src/gobject-inheritance src/gobject-inheritance.p/fruit.c.o src/gobject-inheritance.p/main.c.o src/gobject-inheritance.p/train.c.o -L/app/lib -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group /usr/lib/x86_64-linux-gnu/libglib-2.0.so /usr/lib/x86_64-linux-gnu/libgobject-2.0.so -Wl,--end-group /usr/lib/gcc/x86_64-unknown-linux-gnu/14.2.0/../../../../x86_64-unknown-linux-gnu/bin/ld: src/gobject-inheritance.p/main.c.o: in function `main': /mnt/storage/Programming/.gnome-builder/projects/gobject-inheritance/builds/org.gnome.Example.json-flatpak-org.freedesktop.Platform-24.08-x86_64-main/../../../../../gobject-inheritance/src/main.c:13:(.text+0x10): undefined reference to `example_train_new' collect2: error: ld returned 1 exit status ninja: build stopped: subcommand failed.
我判断问题是链接器找不到example_train_new ()的定义,虽然自行实现该方法看似合理,但教程中并未展示相关实现。请问我哪里出错了?是否需要自行实现这个new方法?
解决方案
是的,你必须自己实现example_train_new()函数。GObject提供的宏(比如G_DECLARE_DERIVABLE_TYPE和G_DEFINE_TYPE_WITH_PRIVATE)只会帮你生成类型系统核心代码(比如类型注册、私有数据访问函数),不会自动生成面向用户的构造函数。
教程里没展示这个实现,是因为它默认你理解:封装g_object_new()为类专属的构造函数是GObject开发的常规做法,这样能提供更友好的API,避免用户直接调用g_object_new()时写错类型标识符。
你只需要在train.c中添加以下实现:
ExampleTrain * example_train_new (void) { // 使用g_object_new创建实例,传入我们的类型标识符和NULL表示无属性参数 return g_object_new(EXAMPLE_TYPE_TRAIN, NULL); }
如果后续需要给构造函数添加参数(比如初始化origin私有属性),可以扩展成这样:
ExampleTrain * example_train_new (const char *origin) { g_return_val_if_fail(origin != NULL, NULL); ExampleTrain *train = g_object_new(EXAMPLE_TYPE_TRAIN, NULL); ExampleTrainPrivate *priv = example_train_get_instance_private(train); priv->origin = g_strdup(origin); return train; }
同时别忘了更新train.h里的函数声明,对应修改参数列表。
链接错误的根源就是你只在头文件里声明了example_train_new(),却没有在.c文件里提供实现,导致链接器无法找到该函数的符号。
内容的提问来源于stack exchange,提问作者Newbyte
相关产品推荐
相关产品推荐

