Сообщить об ошибке.

Основные типы данных модуля ctypes в Python

Содержание:

Соответствие типов модуля ctypes типам языка C и Python.

Модуль ctypes определяет ряд примитивных типов данных, совместимых с языком C:

Тип ctypesТип языка CТип Python
c_bool_Boolbool (1)
c_charchar1-символ, байты
c_wcharwchar_t1-символ, строка
c_bytecharint
c_ubyteunsigned charint
c_shortshortint
c_ushortunsigned shortint
c_intintint
c_uintunsigned intint
c_longlongint
c_ulongunsigned longint
c_longlong__int64 или long longint
c_ulonglongunsigned __int64 или unsigned long longint
c_size_tsize_tint
c_ssize_tssize_t или Py_ssize_tint
c_floatfloatfloat
c_doubledoublefloat
c_longdoublelong doublefloat
c_char_pchar * (NUL terminated)bytes object или None
c_wchar_pwchar_t * (NUL terminated)string или None
c_void_pvoid *int или None
  1. Конструктор принимает любой объект со значением истинности.

Базовый класс для всех основных типов данных модуля ctypes.

ctypes._SimpleCData:

Непубличный класс ctypes._SimpleCData является базовым для всех основных типов данных модуля ctypes. Он упоминается здесь, потому что содержит общие атрибуты основных типов данных ctypes. _SimpleCData является подклассом _CData, поэтому наследует их методы и атрибуты. Типы данных ctypes, которые не являются и не содержат указателей, теперь могут быть обработаны.

У экземпляров есть один атрибут:

SimpleCData.value:

Атрибут SimpleCData.value содержит фактическое значение экземпляра. Для целочисленных и указательных типов это целое число, для символьных типов это объект или строка с одним символом в байтах, для типов символьных указателей это объект или строка в байтах Python.

Когда атрибут value извлекается из экземпляра ctypes, то каждый раз возвращается новый объект. Модуль ctypes не реализует возврат исходного объекта, всегда создается новый объект. То же самое верно для всех других экземпляров объекта ctypes.

Фундаментальные типы данных, когда они возвращаются как результаты вызова внешней функции или, например, при получении элементов поля структуры или элементов массива, прозрачно преобразуются в собственные типы Python. Другими словами, если внешняя функция имеет рестайп ctypes.c_char_p(), то всегда получается объект Python bytes, а не экземпляр ctypes.c_char_p().

Подклассы фундаментальных типов данных не наследуют это поведение. Итак, если рестайп сторонней функции является подклассом c_void_p, то из вызова функции получится экземпляр этого подкласса. Обратившись к атрибуту value, можно получить значение указателя.


Описание основных типов данных модуля ctypes.

ctypes.c_byte:

Класс ctypes.c_byte представляет тип данных языка C signed char и интерпретирует значение как малое целое число. Конструктор принимает необязательный целочисленный инициализатор n. Проверка переполнения не выполняется.

ctypes.c_char:

Класс ctypes.c_char представляет тип данных C char и интерпретирует значение как один символ. Конструктор принимает необязательный инициализатор строки s, длина строки должна быть ровно один символ.

ctypes.c_char_p:

Класс ctypes.c_char_p представляет тип данных C char *, когда он указывает на строку с нулевым завершением. Конструктор принимает целочисленный адрес или объект bytes.

Для общего символьного указателя, который также может указывать на двоичные данные, необходимо использовать POINTER(c_char).

ctypes.c_double:

Класс ctypes.c_double представляет тип данных C double. Конструктор принимает необязательный инициализатор float.

ctypes.c_longdouble:

Класс ctypes.c_longdouble представляет тип данных C long double. Конструктор принимает необязательный инициализатор float.

На платформах, где sizeof(long double) == sizeof(double) - это псевдоним c_double.

ctypes.c_float:

Класс ctypes.c_float представляет тип данных C float. Конструктор принимает необязательный инициализатор float.

ctypes.c_int:

Класс ctypes.c_int представляет тип данных C signed int. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

На платформах, где sizeof(int)==sizeof(long), это псевдоним c_long.

ctypes.c_int8:

Класс ctypes.c_int8 представляет тип данных C 8-bit int. Обычно это псевдоним для ctypes.c_byte.

ctypes.c_int16:

Класс ctypes.c_int16 представляет тип данных C 16-bit int. Обычно это псевдоним для ctypes.c_short.

ctypes.c_int32:

Класс ctypes.c_int32 представляет тип данных C 32-bit int. Обычно это псевдоним для ctypes.c_int.

ctypes.c_int64:

Класс ctypes.c_int64 представляет тип данных C 64-bit int. Обычно это псевдоним для ctypes.c_longlong.

ctypes.c_long:

Класс ctypes.c_long представляет тип данных C signed long со знаком. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

ctypes.c_longlong:

Класс ctypes.c_longlong представляет тип данных C signed long long со знаком. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

ctypes.c_short:

Класс ctypes.c_short представляет тип данных C signed short со знаком. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

ctypes.c_size_t:

Класс ctypes.c_size_t представляет тип данных C size_t.

ctypes.c_ssize_t:

Класс ctypes.c_ssize_t представляет тип данных C ssize_t.

ctypes.c_ubyte:

Класс ctypes.c_ubyte представляет тип данных C unsigned char, он интерпретирует значение как малое целое число. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

ctypes.c_uint:

Класс ctypes.c_uint представляет тип данных C unsigned int. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

На платформах, где sizeof(int) == sizeof(long) является псевдонимом для ctypes.c_ulong.

ctypes.c_uint8:

Класс ctypes.c_uint8 представляет тип данных C 8-bit unsigned int. Обычно это псевдоним для ctypes.c_ubyte.

ctypes.c_uint16:

Класс ctypes.c_uint16 представляет тип данных C 16-bit unsigned int. Обычно это псевдоним для ctypes.c_ushort.

ctypes.c_uint32:

Класс ctypes.c_uint32 представляет тип данных C 32-bit unsigned int. Обычно это псевдоним для ctypes.c_uint.

ctypes.c_uint64:

Класс ctypes.c_uint64 представляет тип данных C 64-bit unsigned int. Обычно это псевдоним для ctypes.c_ulonglong.

ctypes.c_ulong:

Класс ctypes.c_ulong представляет тип данных C unsigned long. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

ctypes.c_ulonglong:

Класс ctypes.c_ulonglong представляет тип данных C unsigned long long. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

ctypes.c_ushort:

Класс ctypes.c_ushort представляет тип данных C unsigned short. Конструктор принимает необязательный целочисленный инициализатор. Проверка переполнения не выполняется.

ctypes.c_void_p:

Класс ctypes.c_void_p представляет тип C void *. Значение представляется в виде целого числа. Конструктор принимает необязательный целочисленный инициализатор.

ctypes.c_wchar:

Класс ctypes.c_wchar представляет тип данных C wchar_t и интерпретирует значение как односимвольную строку Unicode. Конструктор принимает необязательный инициализатор строки, длина строки должна составлять ровно один символ.

ctypes.c_wchar_p:

Класс ctypes.c_wchar_p представляет тип данных C wchar_t *, который должен быть указателем на широкосимвольную строку с нулевым концом. Конструктор принимает целочисленный адрес или строку.

ctypes.c_bool:

Класс ctypes.c_bool представляет тип данных C bool (точнее, _Bool из C99). Его значение может быть True или False. Конструктор принимает любой объект, имеющий истинное значение.

ctypes.HRESULT:

Класс ctypes.HRESULT применяется только в Windows: представляет значение HRESULT, которое содержит информацию об успехе или ошибке для вызова функции или метода.

ctypes.py_object:

Класс ctypes.py_object Представляет тип данных C PyObject *. Вызов этого типа без аргумента создает указатель на NULL PyObject *.

Модуль ctypes.wintypes предоставляет некоторые другие типы данных, специфичные для Windows, например HWND, WPARAM или DWORD. Также определены некоторые полезные структуры, такие как MSG или RECT.


Примеры использования примитивов модуля ctypes.

Все эти типы могут быть созданы путем вызова их с дополнительным инициализатором правильного типа и значения:

>>> from ctypes import *
>>> c_int()
# c_long(0)
>>> c_wchar_p("Hello, World")
# c_wchar_p(140018365411392)
>>> c_ushort(-3)
# c_ushort(65533)

Поскольку эти типы изменяемы, их значение также можно изменить впоследствии:

>>> from ctypes import *
>>> i = c_int(42)
>>> print(i)
c_long(42)
>>> print(i.value)
42
>>> i.value = -99
>>> print(i.value)
-99

Присвоение нового значения экземплярам типов указателей ctypes.c_char_p(), ctypes.c_wchar_p() и ctypes.c_void_p() изменяет место в памяти, на которое они указывают, а не содержимое блока памяти, потому что объекты байтов Python неизменяемы:

>>> from ctypes import *
>>> s = "Hello, World"
>>> c_s = c_wchar_p(s)
>>> print(c_s)
# c_wchar_p(139966785747344)
>>> print(c_s.value)
# Hello World
>>> c_s.value = "Hi, there"

# место в памяти изменилось
>>> print(c_s)              
# c_wchar_p(139966783348904)
>>> print(c_s.value)
# Hi, there

# первый объект не изменился
>>> print(s) 
Hello, World

Необходимо быть осторожным, чтобы не передать их функциям, ожидающим указатели на изменяемую память. Если нужны изменяемые блоки памяти, то у модуля ctypes есть функция ctypes.create_string_buffer(), которая создает их различными способами.

К текущему содержимому блока памяти можно получить доступ или изменить с помощью свойства raw. Если надо получить доступ к нему как к строке с завершающим NUL, то используйте свойство value:

>>> from ctypes import *
# создаем 3-байтовый буфер, 
# инициализированный байтами NUL
>>> p = create_string_buffer(3)
>>> print(sizeof(p), repr(p.raw))
# 3 b'\x00\x00\x00'

# создаем буфер, содержащий строку 
# с завершающим NUL
>>> p = create_string_buffer(b"Hello")
>>> print(sizeof(p), repr(p.raw))
# 6 b'Hello\x00'
>>> print(repr(p.value))
# b'Hello'

# создаем буфер в 10-байт
>>> p = create_string_buffer(b"Hello", 10)
>>> print(sizeof(p), repr(p.raw))
# 10 b'Hello\x00\x00\x00\x00\x00'
>>> p.value = b"Hi"
>>> print(sizeof(p), repr(p.raw))
# 10 b'Hi\x00lo\x00\x00\x00\x00\x00'

Функция ctypes.create_string_buffer() заменяет функцию c_buffer(), которая все еще доступна как псевдоним, а также функцию c_string() из более ранних версий модуля ctypes. Чтобы создать изменяемый блок памяти, содержащий символы Юникода типа wchar_t языка C, используйте функцию ctypes.create_unicode_buffer().