[英]Returning c_char_p from Python ctypes: does the result have to be copied, and if so, how?
I have a function in a library that returns a null-terminated char *, so setup in Python as:我在库中有一个 function,它返回一个空终止的 char *,所以在 Python 中设置为:
my_lib = ctypes.CDLL("my_lib")
my_lib.my_func.restype = ctypes.c_char_p
and this seems to work fine:这似乎工作正常:
my_bytes = my_lib.my_func()
print(my_bytes)
However, the library manages its own memory, and so may manipulate the memory pointed to by char *
later on.但是,该库管理自己的 memory,因此稍后可能会操纵char *
指向的 memory。 To make sure my_bytes
never actually changes, does it need to be copied to another Python object, or has it already been copied?为了确保my_bytes
永远不会真正改变,是否需要将它复制到另一个 Python object,或者它已经被复制了? If it does need to be copied, how to do this?如果确实需要复制,该怎么做?
It's already been copied.它已经被复制了。 A c_char_p
return is automatically converted to an immutable Python bytes
object. If the return type was POINTER(c_char)
then you would have a pointer to the actual memory. Sometimes you need the explicit type if you need to pass that pointer to a function to free the memory later. c_char_p
返回自动转换为不可变的 Python bytes
object。如果返回类型是POINTER(c_char)
,那么您将有一个指向实际 memory 的指针。如果您需要将该指针传递给 function,有时您需要显式类型稍后释放 memory。
A quick proof:快速证明:
from ctypes import *
dll = CDLL('msvcrt')
dll.strcpy.argtypes = c_char_p,c_char_p
dll.strcpy.restype = c_char_p
# strcpy returns a pointer to the destination buffer 'b'
b = create_string_buffer(30)
b2 = dll.strcpy(b,b'hello, world!')
print(b2)
b[0] = b'm' # alter the destination
print(b.value)
print(b2) # no change to b2
print()
dll.strcpy.restype = POINTER(c_char)
b3 = dll.strcpy(b,b'hello there!')
print(b3)
print(b3[:12])
b[0] = b'm' # alter the destination
print(b.value)
print(b3[:12]) # changed!
Output: Output:
b'hello, world!'
b'mello, world!'
b'hello, world!' # no change
<ctypes.LP_c_char object at 0x000001B65E9A5840> # the pointer
b'hello there!' # copied data from pointer
b'mello there!' # change destination buffer
b'mello there!' # cpoied data from pointer again, changed!
c_char_p
by default returns bytes object. So it will print with b'
bytes. c_char_p
默认返回字节 object。因此它将打印b'
字节。 If need to print as string, we can do with .decode('utf-8')
如果需要打印为字符串,我们可以使用.decode('utf-8')
Example:例子:
print(b2) # prints b'hello, world!' as bytes
print(b2.decode('utf-8')) # prints 'hello, world!' as string
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.