8

時々、C だけに存在する gtk/gobject 関数を呼び出す必要がありますが、Python ラッパーを持つオブジェクトを返します。以前は、うまく機能する ctypes に基づくソリューションを使用していました。

http://faq.pygtk.org/index.py?req=show&file=faq23.041.htp

PyGtk ("import gtk") から GObject-introspection ("from gi.repository import Gtk") に切り替えたので、代わりに何を使用できますか?

4

4 に答える 4

8

ある_PyGObject_API時点でインターフェースが変更されました。register_sinkfunc関数を削除する必要がありました。次の作品:

from gi.repository import Gio, GLib
import gi
import ctypes

class _PyGObject_Functions(ctypes.Structure):
   _fields_ = [
       ('register_class',
        ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p,
                          ctypes.c_int, ctypes.py_object,
                          ctypes.py_object)),
       ('register_wrapper',
        ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.py_object)),
       ('lookup_class',
        ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_int)),
       ('newgobj',
        ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)),
       ]

class PyGObjectCPAI(object):
   def __init__(self):
       PyCObject_AsVoidPtr = ctypes.pythonapi.PyCObject_AsVoidPtr
       PyCObject_AsVoidPtr.restype = ctypes.c_void_p
       PyCObject_AsVoidPtr.argtypes = [ctypes.py_object]
       addr = PyCObject_AsVoidPtr(ctypes.py_object(
           gi._gobject._PyGObject_API))
       self._api = _PyGObject_Functions.from_address(addr)

   def pygobject_new(self, addr):
       return self._api.newgobj(addr)

capi = PyGObjectCPAI()

ポインタからオブジェクトを取得するには:

obj = capi.pygobject_new(pointer)

(g)オブジェクトからポインタを取得するには:

pointer = hash(obj)

追加する必要があります。私の場合、これは実際の問題を解決するのに役立ちませんでした。dconfとのインターフェースを試みましたが、dconfはGObjectから継承しないGVariant型の値を返します。残念ながら、PyGI / GObjectは、C(* GVariant)をPythonGLib.Variantに変換するために必要な関数を公開していないようです。最初のアプローチを捨てて、別のことを試みなければならないのはその時だと思います。

于 2012-01-03T14:34:29.147 に答える
4

jdm の回答のコードはCObjectPython 3 と互換性がありません。は Python 2.7 および 3.1 で廃止さCapsuleれ、3.2 から削除されたため、使用するコードを微調整しました( 2.7 および 3.1 以降で利用可能):

import ctypes, gi

class _PyGObject_Functions(ctypes.Structure):
    _fields_ = [
        ('register_class',
            ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p,
                ctypes.c_int, ctypes.py_object, ctypes.py_object)),
        ('register_wrapper',
            ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.py_object)),
        ('lookup_class',
            ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_int)),
        ('newgobj',
            ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)),
        ]

class PyGObjectCAPI(object):
    def __init__(self):
        self._as_void_ptr.restype = ctypes.c_void_p
        self._as_void_ptr.argtypes = [ctypes.py_object]
        addr = self._as_void_ptr(ctypes.py_object(
            gi._gobject._PyGObject_API))
        self._api = _PyGObject_Functions.from_address(addr)

    @staticmethod
    def _as_void_ptr(obj):
        name = ctypes.pythonapi.PyCapsule_GetName(obj)
        return ctypes.pythonapi.PyCapsule_GetPointer(obj, name)

    def pygobject_new(self, addr):
        return self._api.newgobj(addr)

capi = PyGObjectCAPI()

(また、名前を PyGobjectC APIに変更しました。CPAIが何かを表しているかどうかはわかりませんが、この方法の方が私にとってはより理にかなっています。)

于 2015-08-10T06:53:45.547 に答える
0

.typelibインストロスペクション ファイル ( 、 )の出現により、.gir使用されている言語に関係なく同じ API を使用できるようになりました。つまり、API ではない C 関数を使用している場合は、使用することを意図した関数を使用している可能性があります。内部のみ。

于 2011-12-29T17:36:29.873 に答える