¿Cuál es la diferencia entre los punteros LP_ * y los punteros * _p en ctypes? (y la interacción extraña con estructuras)

Tengo problemas para comprender la diferencia entre los punteros LP_ * (p. Ej., LP_c_char) y * _p (p. Ej., C_char_p) en los tipos de Python. ¿Hay documentación que los distinga?

Lo poco que he leído sobre los punteros * _p sugiere que son mejores (de alguna manera no especificada), pero cuando trato de usarlos como campos de estructura, tengo un comportamiento extraño. Por ejemplo, puedo crear una estructura con un campo de puntero 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) 

Y el puntero resultante es:

  

Pero cuando creo una estructura con un campo de puntero 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) 

el campo “ptr” resultante es

  

En otras palabras, el puntero se ha desreferenciado en algún lugar del proceso.

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

Representa el tipo de datos C char * cuando apunta a una cadena terminada en cero. Para un puntero de carácter general que también puede apuntar a datos binarios, debe usarse PUNTERO (c_char).

c_char_p se asigna al tipo de str de Python porque se supone que se está refiriendo a una cadena, que generalmente es el caso cuando se usa char * en C. LP_c_char no hace tal suposición.

Los tipos de datos fundamentales, cuando se devuelven como resultados de llamadas a funciones externas, o, por ejemplo, recuperando miembros de campo de estructura o elementos de matriz, se convierten de forma transparente a tipos de Python nativos. En otras palabras, si una función foránea tiene un tipo de reinicio de c_char_p, siempre recibirá una cadena de Python, no una instancia de c_char_p.