首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从内存地址创建python对象(使用gi.repository)

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

Stack Overflow用户
提问于 2011-12-29 21:13:52
回答 4查看 2.1K关注 0票数 7

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

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

现在我从PyGtk ("import gtk")切换到GObject-introspection ("from gi.repository import Gtk"),我可以用什么来代替呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-01-03 22:34:29

_PyGObject_API接口在某一时刻发生了变化。我需要删除register_sinkfunc函数。以下是工作原理:

代码语言:javascript
复制
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()

要从指针获取对象,请执行以下操作:

代码语言:javascript
复制
obj = capi.pygobject_new(pointer)

要从(G)对象获取指针:

代码语言:javascript
复制
pointer = hash(obj)

我必须补充说,在我的情况下,这并没有帮助我解决我的实际问题。我试图与dconf接口,但dconf返回的值类型为GVariant,它不是从GObject继承的。不幸的是,PyGI/GObject似乎没有公开必要的函数来将C (*GVariant)转换为Python。我猜这是你不得不抛弃最初的方法,尝试一些不同的东西的时候。

票数 7
EN

Stack Overflow用户

发布于 2015-08-10 14:53:46

jdm's answer中的代码与Python3不兼容。由于CObject在Python2.7和3.1中是deprecated,并从3.2开始删除,因此我调整了代码以使用Capsule ( 2.7和3.1版本中的available):

代码语言:javascript
复制
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()

(我还将其重命名为PyGobjectCAPI --不确定CPAI是否代表什么,但这样对我来说更有意义。)

票数 3
EN

Stack Overflow用户

发布于 2017-04-05 00:06:58

AlliedEnvy update以来PyGOject api已更改

代码语言:javascript
复制
import gi
import ctypes
from ctypes import pythonapi

class _PyGObject_Functions(ctypes.Structure):
    _fields_ = [
        ('pygobject_register_class',
            ctypes.PYFUNCTYPE(ctypes.c_void_p)),
        ('pygobject_register_wrapper',
            ctypes.PYFUNCTYPE(ctypes.c_void_p)),
        ('pygobject_lookup_class',
            ctypes.PYFUNCTYPE(ctypes.c_void_p)),
        ('pygobject_new',
            ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)),
        ]

  class PyGObjectCAPI(object):
    def __init__(self):
        addr = self._as_void_ptr(gi._gobject._PyGObject_API)
        self._api = _PyGObject_Functions.from_address(addr)

    @classmethod
    def _capsule_name(cls, capsule):
        pythonapi.PyCapsule_GetName.restype = ctypes.c_char_p
        pythonapi.PyCapsule_GetName.argtypes = [ctypes.py_object]
        return pythonapi.PyCapsule_GetName(capsule)

    @classmethod
    def _as_void_ptr(cls, capsule):
        name = cls._capsule_name(capsule)
        pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
        pythonapi.PyCapsule_GetPointer.argtypes = [
            ctypes.py_object, ctypes.c_char_p]
        return pythonapi.PyCapsule_GetPointer(capsule, name)

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

capi = PyGObjectCAPI()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8668333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档