问题描述
我在玩 libpeas
时偶然发现了 gobject-introspection 工作方式的问题。
在 libpeas
中有一个类型叫做 PluginLoader
(参见 here)。
有一个名为 create_extension
的方法返回 PeasExtension *
,它是一个指向 GObject
的点。当我将此类型添加到 gobject-introspection 并检查此方法的生成 GIR 文件时,我可以看到它被标记为 introspectable="0"
:
<field name="create_extension" introspectable="0">
<callback name="create_extension" introspectable="0">
<source-position filename="../libpeas/peas-plugin-loader.h"
line="60"/>
<return-value>
<type name="Extension" c:type="PeasExtension*"/>
</return-value>
<parameters>
<parameter name="loader" transfer-ownership="none">
<type name="PluginLoader" c:type="PeasPluginLoader*"/>
</parameter>
<parameter name="info" transfer-ownership="none">
<type name="PluginInfo" c:type="PeasPluginInfo*"/>
</parameter>
<parameter name="ext_type" transfer-ownership="none">
<type name="GType" c:type="GType"/>
</parameter>
<parameter name="n_parameters" transfer-ownership="none">
<type name="guint" c:type="guint"/>
</parameter>
<parameter name="parameters" transfer-ownership="none">
<type name="GObject.Parameter" c:type="GParameter*"/>
</parameter>
</parameters>
</callback>
</field>
当我将返回值更改为 void *
并重新编译时,introspectable="0"
属性从 GIR 文件中消失了。如果我将其更改为 GObject *
,则 introspectable="0"
属性仍然存在。
当它返回一个 GObject 的实例(一个指针)时,它看起来像是不可内省的。但我不明白为什么?
通过阅读 gobject introspection 文档,看起来返回 GObject 实例是一个有效的用例。也许这与 PluginLoader
类型是抽象的而这是一个虚方法有关?
在不改变方法签名的情况下,任何注解都可以帮助使这个对象自省吗?
解决方法
在 Philip 在评论中的帮助下,我设法解决了这个问题。
g-ir-scanner
的输出中实际上有一条消息说:
../../source/libpeas/libpeas/peas-plugin-loader.h:91: Warning: Peas: peas_plugin_loader_create_extension: return value: Missing (transfer) annotation
通过这条消息,我了解到要使虚函数 create_extension
内省,我必须添加注释,但不是在 PeasPluginLoaderClass
定义中的函数指针处,而是在访问器函数 {{1 }}。