我正在使用以下代码读取svg:from ctypes import CDLL, POINTER, Structure, byref, utilfrom ctypes import c_bool, c_byte, c_void_p, c_int, c_double, c_uint32, c_char_pclass _PycairoContext(Structure):_fi...

我正在使用以下代码读取svg:
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),这会泄漏内存.我很确定这是由于错误地使用了ctypes&指针,但我找不到解决此问题的方法.
解决方法:
根据rsvg_handle_new的文档,使用g_object_unref释放句柄.此外,如果失败的调用分配了GError,则在获取代码和消息后,必须使用g_error_free释放错误.
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类的__del__方法中释放该句柄:
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
沃梦达教程
本文标题为:osx中的rsvg python内存泄漏(ctypes?)


基础教程推荐
猜你喜欢
- Python3.7 + Yolo3实现识别语音播报功能 2023-08-04
- CentOS7下部署Python3+Django+uwsgi+Nginx 2023-09-03
- python-挂钩并在Windows消息队列中记录“所有内容” 2023-11-10
- 【转】新装的CentOS 7安装python3 2023-09-03
- Python之Linux下的virtualenv&&virtualenvwrapper 2023-09-04
- python——多线程与多进程 2023-11-10
- 通过OpenCV实现对指定颜色的物体追踪 2023-08-11
- python通过内置模块监控磁盘、内存、CPU、负载 2023-09-03
- 基于Python编写一个自动关机程序 2023-08-11
- 浅谈Python3中打开文件的方式(With open) 2022-09-03