我正在尝试按照 GObject 教程 来实现我的第一个 GObject 类。到目前为止,我已经想出了这段代码:
火车.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
火车.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);
}
当然,它还没有真正做任何事情,但它可以编译,所以我想我可以尝试实例化它。鉴于在标头中我原型
example_train_new ()
,我想我可以在我的 main.c 文件中使用它来实例化此类,但没有骰子:
[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 ()
的任何定义。虽然自己定义它似乎是明智的,但在链接的教程中我没有在任何地方看到这样做。
我在这里做错了什么?我应该自己实施“新”方法吗?
我最终查看了 GTK 4 源代码中的一些实现来了解如何做到这一点。具体来说,gtk/gtkstack.c。
对于上面的情况,像这样的简单构造函数似乎就足够了:
ExampleTrain *
example_train_new (void)
{
return g_object_new (EXAMPLE_TYPE_TRAIN, NULL);
}
但是,如果还想在构造函数中设置上面示例中的私有
origin
属性,您可以这样做:
ExampleTrain *
example_train_new (const char *origin)
{
ExampleTrain *self = g_object_new (EXAMPLE_TYPE_TRAIN, NULL);
ExampleTrainPrivate *priv = example_train_get_instance_private (self);
priv->origin = origin;
return self;
}
如果您想设置公共属性,您可以执行与上述相同的操作,但使用
self
代替 priv
。所以,整个example_train_get_instance_private (self)
部分可以被删除。