What is the difference between LP_ * pointers and * _p pointers in ctypes? (and weird interaction with structures)

It's hard for me to understand the difference between LP_ * pointers (like LP_c_char) and * _p (like c_char_p) in Python types. Is there any documentation that distinguishes them?

Little has I read about * _p pointers, it says they are better (in some vague way), but when I try to use them as structural fields, I get strange behavior. For example, I can create a structure with an LP_c_char pointer field:

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) 

And the resulting pointer:

 <class 'ctypes.LP_c_char'> 

But when I create a structure with a c_char_p pointer field:

 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) 

received field "ptr"

 <type 'str'> 

In other words, the pointer was dereferenced somewhere in the process.

+6
source share
1 answer

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

Represents the C char * data type when it points to a null-terminated string. For a generic pointer that can also point to binary data, you must use POINTER (c_char).

c_char_p maps to the Python str type because it assumes that you are referring to a string that usually occurs when you use char * in C. LP_c_char does not make such an assumption.

Fundamental data types returned as results of calling external functions or, for example, by extracting elements of a structure field or array elements, are transparently converted to native Python types. In other words, if a foreign function has restype c_char_p, you will always get a Python string, not a c_char_p instance.

+9
source

Source: https://habr.com/ru/post/892776/


All Articles