2011-12-29 12 views

Odpowiedz

6

Interfejs _PyGObject_API zmienił się w pewnym momencie. Musiałem zrezygnować z funkcji register_sinkfunc. Następujące prace:

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() 

Aby uzyskać obiekt od wskaźnika:

obj = capi.pygobject_new(pointer) 

aby uzyskać wskaźnik z (g) obiektu:

pointer = hash(obj) 

muszę dodawać, w mój przypadek nie pomógł mi rozwiązać mojego prawdziwego problemu. Próbowałem interfejs z dconf, ale dconf zwraca wartości typu GVariant, który nie dziedziczy z GObject. Wygląda na to, że PyGI/GObject niestety nie ujawnia potrzebnych funkcji do zmiany C (* GVariant) w Python GLib.Variant. Sądzę, że to z tych czasów, kiedy trzeba odrzucić swoje początkowe podejście i spróbować czegoś innego.

0

Po pojawieniu się plików instrospekcji (.typelib, .gir) ten sam interfejs API powinien być dostępny niezależnie od używanego języka, to znaczy, jeśli używasz funkcji C, która nie znajduje się w interfejsie API, prawdopodobnie używasz funkcja przeznaczona wyłącznie do użytku wewnętrznego.

+2

Teoretycznie to prawda. Jednak chciałem użyć funkcji z libdconf i obecnie nie ma na to powiązania w moim systemie operacyjnym (Ubuntu Oneric). Możliwe jest również, że mamy do czynienia z niestandardową biblioteką (nie będącą częścią Gtk & co.), Która zwraca wskaźnik do GObject, więc w niszowych przypadkach może to być przydatne. – jdm

+0

@jdm Rozumiem, dziękuję za twoją opinię. – jcollado

2

Kod w jdm's answer nie jest kompatybilny z Python 3. Ponieważ CObject jest deprecated Pythona 2.7 i 3.1, wychodząc z 3,2 usunięte, że manipulowane kod użyć Capsule (available w 2,7 i od 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() 

(ja też przemianowano go PyGobjectC API. - nie jestem pewien, czy CPAI stanął na coś, ale to więcej sensu do mnie w ten sposób)

1

PyGOject api zmieniło od AlliedEnvy update

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() 
Powiązane problemy