ctypes中的LP_ *指针和* _p指针有什么区别?(以及与结构的怪异互动)


问题内容

我在理解Python ctypes中的LP _ (例如LP_c_char)和
_p(例如c_char_p)指针之间的区别时遇到了麻烦。是否有文档将它们区分开?

我对*
_p指针的了解很少,这表明它们更好(以某种未指定的方式),但是当我尝试将它们用作结构字段时,会出现奇怪的行为。例如,我可以使用LP_c_char指针字段创建一个结构:

import ctypes
char = ctypes.c_char('a')
class LP_Struct(ctypes.Structure):
    _fields_ = [('ptr', ctypes.POINTER(ctypes.c_char))]

struct = LP_Struct(ctypes.pointer(char))
print type(struct.ptr)

结果指针是:

<class 'ctypes.LP_c_char'>

但是,当我使用c_char_p指针字段创建结构时:

class Struct_p(ctypes.Structure):

    _fields_ = [('ptr', ctypes.c_char_p)]

p = ctypes.pointer(char)
struct = Struct_p(ctypes.cast(p, ctypes.c_char_p))
print type(struct.ptr)

结果“ ptr”字段为

<type 'str'>

换句话说,指针已在该过程中的某个地方被取消引用。


问题答案:

http://docs.python.org/library/ctypes.html#ctypes.c_char_p

当C char *数据类型指向以零结尾的字符串时,表示它。对于也可能指向二进制数据的通用字符指针,必须使用POINTER(c_char)。

c_char_p之所以映射到Python的str类型,是因为它假定您要引用一个字符串,通常char *在C语言中使用时就是LP_c_char这种情况。

基本数据类型在作为外部函数调用结果返回时,或者例如通过检索结构字段成员或数组项而返回时,将透明地转换为本机Python类型。换句话说,如果外部函数的重新类型为c_char_p,您将始终收到Python字符串,而不是c_char_p实例。