首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rsvg python内存泄漏在osx (ctype?)

rsvg python内存泄漏在osx (ctype?)
EN

Stack Overflow用户
提问于 2014-05-22 04:23:35
回答 1查看 223关注 0票数 3

我使用以下代码读取svg:

代码语言:javascript
复制
from ctypes import CDLL, POINTER, Structure, byref, util
from ctypes import c_bool, c_byte, c_void_p, c_int, c_double, c_uint32, c_char_p

class _PycairoContext(Structure):
    _fields_ = [("PyObject_HEAD", c_byte * object.__basicsize__),
                ("ctx", c_void_p),
                ("base", c_void_p)]

class _RsvgProps(Structure):
    _fields_ = [("width", c_int), ("height", c_int),
                ("em", c_double), ("ex", c_double)]

class _GError(Structure):
    _fields_ = [("domain", c_uint32), ("code", c_int), ("message", c_char_p)]


def _load_rsvg(rsvg_lib_path=None, gobject_lib_path=None):
    if rsvg_lib_path is None:
        rsvg_lib_path = util.find_library('rsvg-2')
    if gobject_lib_path is None:
        gobject_lib_path = util.find_library('gobject-2.0')
    l = CDLL(rsvg_lib_path)
    g = CDLL(gobject_lib_path)
    g.g_type_init()

    l.rsvg_handle_new_from_file.argtypes = [c_char_p, POINTER(POINTER(_GError))]
    l.rsvg_handle_new_from_file.restype = c_void_p
    l.rsvg_handle_render_cairo.argtypes = [c_void_p, c_void_p]
    l.rsvg_handle_render_cairo.restype = c_bool
    l.rsvg_handle_get_dimensions.argtypes = [c_void_p, POINTER(_RsvgProps)]

    return l    

_librsvg = _load_rsvg()


class Handle(object):
    def __init__(self, path):
        lib = _librsvg
        err = POINTER(_GError)()
        self.handle = lib.rsvg_handle_new_from_file(path, byref(err))
        if self.handle is None:
            gerr = err.contents
            raise Exception(gerr.message)
        self.props = _RsvgProps()
        lib.rsvg_handle_get_dimensions(self.handle, byref(self.props))

    def render_cairo(self, ctx):
        """Returns True is drawing succeeded."""
        z = _PycairoContext.from_address(id(ctx))
        return _librsvg.rsvg_handle_render_cairo(self.handle, z.ctx)

(来自Error with Python ctypes and librsvg)

我调用img = Handle(path),这会泄漏内存。我很确定这是由于不正确地使用ctype&指针,但我找不到解决这个问题的方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-23 08:20:33

根据rsvg_handle_new的文档,用g_object_unref释放句柄。另外,如果一个失败的调用分配了一个GError,那么在您获得代码和消息之后,您必须使用g_error_free释放错误。

代码语言:javascript
复制
from ctypes import *
from ctypes.util import find_library

_gobj = CDLL(find_library("gobject-2.0"))
_glib = CDLL(find_library("glib-2.0"))

class _GError(Structure):
    _fields_ = [("domain", c_uint32), 
                ("code", c_int), 
                ("message", c_char_p)]

_GErrorP = POINTER(_GError)

_glib.g_error_free.restype = None
_glib.g_error_free.argtypes = [_GErrorP]

_gobj.g_object_unref.restype = None
_gobj.g_object_unref.argtypes = [c_void_p]

您可以释放Handle类的Handle方法中的句柄:

代码语言:javascript
复制
class Handle(object):
    _gobj = _gobj # keep a valid ref for module teardown

    # ...

    def __del__(self):
        if self.handle:
            self._gobj.g_object_unref(self.handle)
            self.handle = None
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23797789

复制
相关文章

相似问题

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