我的 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
无内存操作?
在
ctypes
中,c_char_p
转换一个空终止的Cchar*
并返回一个Pythonbytes
对象。指针丢失了。
使用
c_void_p
或POINTER(c_char)
保持指针。 string_at
可用于读取返回地址处的空终止字符串。
未测试:
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_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()
if Err: raise LibErr(Err)
ans = ctypes.string_at(output).decode()
# free memory
libXML.xmlMemFree.argtypes = ctypes.c_void_p,
libXML.xmlMemFree.restype = None
libXML.xmlMemFree(output)
return ans