ctypes: вызов библиотек C из Python
Загружайте общие библиотеки и вызывайте функции C с помощью ctypes.
«ctypes: вызов библиотек C из Python» — бесплатный урок Python Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.
Что такое ctypes
ctypes — это модуль стандартной библиотеки для загрузки разделяемых библиотек на C и вызова их функций из Python — компиляция не требуется.
import ctypes
# Load the C standard library
libc = ctypes.CDLL("libc.so.6") # Linux
# libc = ctypes.CDLL("libSystem.dylib") # macOS
libc.puts(b"Hello from C!")Загрузка библиотек
Используйте ctypes.CDLL для соглашения о вызовах cdecl (его используют большинство библиотек на C), а WinDLL — для API Windows со соглашением stdcall.
import ctypes
# Platform-independent approach:
import ctypes.util
libm_name = ctypes.util.find_library("m")
libm = ctypes.CDLL(libm_name)
result = libm.sqrt
result.restype = ctypes.c_double
result.argtypes = [ctypes.c_double]
print(result(2.0)) # 1.4142...Типы данных C
Сопоставляйте типы Python с типами C с помощью классов ctypes: c_int, c_double, c_char_p, c_void_p и т. д.
import ctypes
x = ctypes.c_int(42)
print(x.value) # 42
d = ctypes.c_double(3.14)
print(d.value) # 3.14
s = ctypes.c_char_p(b"hello")
print(s.value) # b"hello"Настройка argtypes и restype
Всегда объявляйте argtypes (типы параметров) и restype (возвращаемый тип), чтобы избежать незаметных сбоев из-за несовпадения типов.
import ctypes, ctypes.util
libm = ctypes.CDLL(ctypes.util.find_library("m"))
libm.pow.argtypes = [ctypes.c_double, ctypes.c_double]
libm.pow.restype = ctypes.c_double
print(libm.pow(2.0, 10.0)) # 1024.0Передача указателей
Используйте ctypes.byref(var) или ctypes.pointer(var), чтобы передать указатель на переменную C.
import ctypes
libc = ctypes.CDLL(None) # None = current process
value = ctypes.c_int(0)
# Passing pointer to C function:
# libc.some_func(ctypes.byref(value))
print(value.value)Структуры
Определяйте структуры C, создавая подкласс ctypes.Structure и перечисляя поля в _fields_.
import ctypes
class Point(ctypes.Structure):
_fields_ = [
("x", ctypes.c_double),
("y", ctypes.c_double),
]
p = Point(1.0, 2.0)
print(p.x, p.y) # 1.0 2.0Массивы
Создавайте массивы C с помощью TypeClass * N.
import ctypes
IntArray5 = ctypes.c_int * 5
arr = IntArray5(10, 20, 30, 40, 50)
for v in arr:
print(v, end=" ") # 10 20 30 40 50Обратные вызовы (указатели на функции)
Используйте ctypes.CFUNCTYPE, чтобы создать вызываемую из C функцию Python и передать её как обратный вызов.
import ctypes
CompareFunc = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)
def my_compare(a, b):
return a - b
c_compare = CompareFunc(my_compare)
# Pass c_compare to a C function expecting a comparatorЗагрузка DLL Windows
В Windows используйте ctypes.WinDLL для DLL, применяющих соглашение stdcall (например, для API Windows).
import ctypes # Windows only
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
kernel32.GetTickCount.restype = ctypes.c_ulong
print(kernel32.GetTickCount())Обработка ошибок
Проверяйте ctypes.get_last_error() (Windows) или используйте обработку try/except на уровне Python для ошибок, возвращаемых в виде специальных значений.
import ctypes
# Many C functions return -1 or NULL on error:
result = some_c_function()
if result == -1:
raise OSError("C function failed")
# For errno on POSIX:
import os
if result < 0:
raise OSError(os.strerror(ctypes.get_errno()))Практический пример: SHA-256 с OpenSSL
Вызывайте SHA256 из OpenSSL напрямую через ctypes, без библиотеки привязки к Python.
import ctypes, ctypes.util
libcrypto = ctypes.CDLL(ctypes.util.find_library("crypto"))
SHA256 = libcrypto.SHA256
SHA256.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_char_p]
SHA256.restype = ctypes.c_char_p
buf = ctypes.create_string_buffer(32)
SHA256(b"hello", 5, buf)
print(buf.raw.hex())Быстрая проверка
Почему следует всегда задавать argtypes и restype для функции ctypes?
Итоги
ctypes загружает разделяемые библиотеки на C без компиляции. Объявляйте argtypes и restype для каждой функции. Используйте Structure для структур C, TypeClass * N для массивов и CFUNCTYPE для обратных вызовов.
Часто задаваемые вопросы
Урок «ctypes: вызов библиотек C из Python» бесплатный?
Да — полный текст урока «ctypes: вызов библиотек C из Python» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.
Чему я научусь в уроке «ctypes: вызов библиотек C из Python»?
Загружайте общие библиотеки и вызывайте функции C с помощью ctypes. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Python Academy?
Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «ctypes: вызов библиотек C из Python»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Python Academy?
Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Зачем нужны расширения C: применение и компромиссы
- ctypes: вызов библиотек C из Python
- cffi: интерфейс внешних функций C
- Написание расширения Python на C