我的Python脚本是:
def xmlEncodeSpecialChars(doc: xmlDoc, input: str) -> str:
'''
Do a global encoding of a string, replacing the predefined entities this routine is reentrant, and result must be deallocated.
doc: the document containing the string
input: A string to convert to XML.
Returns: A newly allocated string with the substitution done.'''
libXML = LibXML2() # DSO/DLL
libXML.xmlEncodeSpecialChars.restype = ctypes.c_char_p
libXML.xmlEncodeSpecialChars.argtypes = ctypes.c_void_p, ctypes.c_char_p,
output: ctypes.c_char_p = libXML.xmlEncodeSpecialChars(doc, input.encode());
Err = xmlGetLastError()
if Err: raise LibErr(Err)
ans = output.decode()
# free memory
libXML.xmlMemFree.argtypes = ctypes.c_char_p, ;
libXML.xmlMemFree(output)
return ans
它正确地返回了一个转义字符串,但是xmlMemFree()在Python中生成了一个Memory tag error
,尽管对同一DLL的等效C调用也可以正常工作。
如何设置ctypes
内存释放操作?
---编辑---
最低可复制(Linux)设置为:
def xmlEncodeSpecialChars(doc: xmlDoc, input: str) -> str:
'''
Do a global encoding of a string, replacing the predefined entities this routine is reentrant, and result must be deallocated.
doc: the document containing the string
input: A string to convert to XML.
Returns: A newly allocated string with the substitution done.'''
libXML = ctypes.CDLL ("libxml2.so.2") # DSO/DLL
libXML.xmlEncodeSpecialChars.restype = ctypes.c_void_p
libXML.xmlEncodeSpecialChars.argtypes = ctypes.c_void_p, ctypes.c_char_p,
output: ctypes.c_void_p = libXML.xmlEncodeSpecialChars(doc, input.encode());
Err = xmlGetLastError() # check for library error
if Err: raise LibErr(Err)
ans = ctypes.cast(output, ctypes.c_char_p).value.decode() # convert to Python str
libXML.xmlMemFree.argtypes = ctypes.c_void_p, ;libXML.xmlMemFree(output); # free memory, FIXME
return ans
print(xmlEncodeSpecialChars(None, "<root>Some text with < and > characters</root>"))
1条答案
按热度按时间kr98yfug1#
在
ctypes
中,c_char_p
转换以null结尾的Cchar*
并返回Pythonbytes
对象。指针丢失。使用
c_void_p
或POINTER(c_char)
来维护指针。string_at
可用于读取返回地址处的空终止字符串。未测试: