从内存地址创建python对象(使用gi.repository)

jdm*_*jdm 6 python ctypes pygobject

有时我需要调用一个只存在于C中的gtk/gobject函数,但返回一个带有python包装器的对象.以前我使用过基于ctypes的解决方案,效果很好:

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

现在我从PyGtk("import gtk")转向GObject-introspection("来自gi.repository import Gtk"),我可以使用什么呢?

jdm*_*jdm 6

_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()
Run Code Online (Sandbox Code Playgroud)

要从指针获取对象:

obj = capi.pygobject_new(pointer)
Run Code Online (Sandbox Code Playgroud)

从(g)对象获取指针:

pointer = hash(obj)
Run Code Online (Sandbox Code Playgroud)

我必须补充一点,在我的情况下,这并没有帮助我解决我的实际问题.我试图与dconf接口,但dconf返回GVariant类型的值,它不从GObject继承.遗憾的是,PyGI/GObject似乎没有公开必要的函数来将C(*GVariant)变成Python GLib.Variant.我想那时你必须抛弃你的初始方法并尝试不同的东西.