2

まず、いくつかのコンテキスト: 私は PyGObject を使用して中規模のアプリケーションを作成した Python 開発者であり、GObject Introspection を利用して GSettings などにアクセスしています。私の Python オブジェクトの一部は、実際には GObject.GObject をサブクラス化しています。 GObject をかなり広範囲に使用します。

最近、C ライブラリを GObject (Shotwell/Vala で使用される gexiv2) でラップする特定のライブラリに注目しましたが、現在はイントロスペクションをサポートしていません。Python からアクセスできるように gexiv2 にイントロスペクション サポートを追加することに興味がありますが、このトピックをどこから始めればよいかさえわかりません。

イントロスペクションと VAPI について調べていると、イントロスペクション アノテーションから VAPI を自動的に生成できるという事実に言及しているドキュメントがたくさんあります。VAPI を指定してイントロスペクション アノテーションを自動的に生成することは可能ですか?

ありがとう。

4

2 に答える 2

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) が生成されます。

于 2012-06-25T22:55:39.437 に答える
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を使用することを心から望んでいます).

于 2012-06-30T07:37:16.653 に答える