首先,一些上下文:我是Python开发人员,他使用PyGObject编写了一个中型应用程序,利用GObject Introspection来访问GSettings等等。我的一些Python对象实际上是GObject.GObject的子类,所以我非常广泛地使用GObject。
最近,我注意到某个库在GObject中封装了一个C库(gexiv2,由Shotwell / Vala使用),但它目前还不支持内省。我有兴趣为gexiv2添加内省支持,以便我可以从Python访问它,但我甚至不知道从哪里开始这个主题。
当我研究内省和VAPI时,我看到许多文档引用了VAPI可以从内省注释中自动生成的事实......但是那个已经有VAPI但没有内省的项目呢?给定VAPI可以自动生成内省注释吗?
感谢。
答案 0 :(得分:2)
VAPI绑定不一定与GObject内省有关。例如,POSIX,Linux,libudev和其他绝对不是基于GObject的东西都有VAPI绑定。没有直接的方法将VAPI转换为GObject绑定。
但是,如果你有C头文件和一个工作库,那么你通常可以从库中构建一个GObject内省文件。对于gexiv2,下载并构建源代码,然后执行:
g-ir-scanner -I gexiv2 gexiv2/gexiv2-{metadata,managed-stream,preview-properties,preview-image,log,startup}.h -n GExiv2 --library libgexiv2.la --pkg gobject-2.0
这将生成一个可以在Python中使用的GIR绑定(XML)。
答案 1 :(得分:1)
好吧,在厌倦了手工复制VAPI定义到内省注释的繁琐之后,我写了这个(粗略)脚本来为我做这些:
#!/bin/env python
import sys
from collections import defaultdict
ANNOTATION = """/**
* %s:
%s *
* Returns:%s
*/
"""
PARAMETER = """ * @%s:%s
"""
methods = defaultdict(set)
attrs = defaultdict(dict)
with open(sys.argv[1]) as vapi:
for line in vapi:
tokens = line.split()
try:
names = tuple(tokens[0].split('.'))
except IndexError:
continue
attrs[names] = {}
for attribute in tokens[1:]:
key, val = attribute.split('=')
if val == '"1"': val = True
if val == '"0"': val = False
attrs[names][key] = val
methods[names[0]]
if len(names) > 1:
methods[names[0]].add(names[-1])
for method in methods:
params = ''
for param in methods[method]:
param_attributes = ''
param_attrs = attrs[(method, param)]
if param_attrs.get('hidden'):
param_attributes += ' (skip)'
if param_attrs.get('is_out'):
param_attributes += ' (out)'
if param_attrs.get('transfer_ownership'):
param_attributes += ' (transfer full)'
elif 'transfer_ownership' in param_attrs:
param_attributes += ' (transfer none)'
if param_attrs.get('array_null_terminated'):
param_attributes += ' (array zero-terminated=1)'
if param_attrs.get('array_length_pos'):
param_attributes += ' (array length=FIXME)'
if param_attributes:
param_attributes += ':'
params += PARAMETER % (param, param_attributes)
attributes = ''
method_attrs = attrs[(method,)]
if method_attrs.get('transfer_ownership'):
attributes += ' (transfer full)'
elif 'transfer_ownership' in method_attrs:
attributes += ' (transfer none)'
if method_attrs.get('nullable'):
attributes += ' (allow-none)'
if method_attrs.get('array_null_terminated'):
attributes += ' (array zero-terminated=1)'
if attributes:
attributes += ':'
print ANNOTATION % (method, params, attributes)
这显然有一些缺点:它没有在代码中插入注释,只是打印它们,所以你必须做相当多的复制&粘贴,把一切都放到正确的地方。它也不能很好地处理数组,但至少可以让你知道什么时候你需要手动修复数组。总而言之,运行此脚本然后按摩结果比手动解析要少得多。我在这里发布它是希望它被谷歌拿起并且其他人可能会受益一天(尽管我非常希望所有基于GObject的项目从这里开始只是从注释开始然后使用vapigen)。