ctypes
The Python ctypes module provides C-compatible data types and allows calling functions exported from shared libraries or DLLs, enabling Python code to interface with C libraries without writing a C extension.
Here’s a quick look at loading a shared library and calling a C function:
>>> import ctypes
>>> import ctypes.util
>>> libc = ctypes.CDLL(ctypes.util.find_library("c"))
>>> libc.strlen(b"Hello, World!")
13
Key Features
- Loads shared libraries and DLLs using
cdecl,stdcall, and OLE calling conventions - Provides C-compatible fundamental types that map to Python types
- Supports defining C structures, unions, and bit fields as Python classes
- Allows specifying argument and return types for type-safe function calls
- Enables creating callback functions that C code can invoke
- Provides pointer types and memory manipulation utilities
- Works on Windows, Linux, and macOS
Frequently Used Classes and Functions
| Object | Type | Description |
|---|---|---|
ctypes.CDLL |
Class | Loads shared libraries using the cdecl calling convention |
ctypes.WinDLL |
Class | Loads Windows DLLs using the stdcall calling convention |
ctypes.Structure |
Class | Base class for defining C-compatible structure types |
ctypes.Union |
Class | Base class for defining C-compatible union types |
ctypes.CFUNCTYPE() |
Function | Creates a C-callable function type with the cdecl calling convention |
ctypes.POINTER() |
Function | Creates a pointer type for a given ctypes type |
ctypes.byref() |
Function | Creates a lightweight reference to a ctypes instance for use as a pointer argument |
ctypes.cast() |
Function | Converts a ctypes instance to a different pointer type |
ctypes.sizeof() |
Function | Returns the size in bytes of a ctypes type or instance |
ctypes.create_string_buffer() |
Function | Creates a mutable byte buffer suitable for use as a C string |
ctypes.util.find_library() |
Function | Locates a shared library by name on the current platform |
ctypes.c_int |
Class | Maps a C int to a Python int |
ctypes.c_char_p |
Class | Maps a C char * to Python bytes or None |
Examples
Setting argument and return types before calling a C function:
>>> import ctypes, ctypes.util
>>> from ctypes import CDLL, c_int
>>> libc = CDLL(ctypes.util.find_library("c"))
>>> libc.abs.restype = c_int
>>> libc.abs.argtypes = [c_int]
>>> libc.abs(-42)
42
Defining a C structure and accessing its fields:
>>> from ctypes import Structure, c_int
>>> class Point(Structure):
... _fields_ = [("x", c_int), ("y", c_int)]
...
>>> p = Point(10, 20)
>>> p.x, p.y
(10, 20)
Passing pointer arguments with byref() to receive output values from a C function:
>>> import ctypes, ctypes.util
>>> from ctypes import c_int, c_float, byref, create_string_buffer
>>> libc = ctypes.CDLL(ctypes.util.find_library("c"))
>>> i = c_int()
>>> f = c_float()
>>> s = create_string_buffer(32)
>>> libc.sscanf(b"42 3.14 hello", b"%d %f %s", byref(i), byref(f), s)
3
>>> i.value, round(f.value, 2), s.value
(42, 3.14, b'hello')
Common Use Cases
The most common tasks for ctypes include:
- Calling functions from C system libraries without writing a C extension module
- Wrapping platform-specific APIs on Windows, Linux, or macOS
- Passing structured data through C structures and arrays to and from library functions
- Implementing Python callback functions that a C library will invoke
- Performing low-level memory operations with pointers and buffers
Real-World Example
The following script uses ctypes to call the C standard library’s qsort() function, supplying a Python function as the comparison callback:
ctypes_qsort.py
import ctypes
import ctypes.util
from ctypes import CDLL, CFUNCTYPE, POINTER, c_int, sizeof
libc = CDLL(ctypes.util.find_library("c"))
IntArray5 = c_int * 5
numbers = IntArray5(5, 1, 7, 33, 99)
CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
@CMPFUNC
def compare_ints(a, b):
return a[0] - b[0]
libc.qsort(numbers, len(numbers), sizeof(c_int), compare_ints)
print(list(numbers))
Run it:
$ python ctypes_qsort.py
[1, 5, 7, 33, 99]
CFUNCTYPE wraps the Python comparison function into a C-callable type, and qsort() invokes it for each comparison during the sort.
Related Resources
Tutorial
Building a Python C Extension Module
In this tutorial, you'll learn how to write Python interfaces in C. Find out how to invoke C functions from within Python and build Python C extension modules. You'll learn how to parse arguments, return values, and raise custom exceptions using the Python API.
For additional information on related topics, take a look at the following resources:
- Pointers in Python: What's the Point? (Tutorial)
- Bytes Objects: Handling Binary Data in Python (Tutorial)
- Pointers and Objects in Python (Course)
- Python Bytes (Quiz)
By Leodanis Pozo Ramos • Updated March 25, 2026