A Python library that provides a dataclass-like interface for creating ctypes structures, making it easier to work with C libraries and data structures in Python.
- Dataclass-like syntax: Define C structures using familiar Python class syntax with type hints
- Automatic field management: Fields are automatically converted to ctypes types based on type annotations
- Array support: Built-in support for fixed-size arrays with proper type checking
- Pointer support: Easy handling of C pointers with type safety
- Default values: Support for default field values and factories
- Inheritance: Full support for class inheritance in C structures
- Memory layout control: Control structure packing and alignment
- C function binding: Decorator for easy binding to C library functions
pip install cbridge
from cbridge import CStruct
from cbridge import types
class Point(CStruct):
x: types.int32
y: types.int32
class Rectangle(CStruct):
top_left: Point
bottom_right: Point
color: types.uint32 = 0xFF0000 # Default value
# Create instances
point = Point(x=10, y=20)
rect = Rectangle(
top_left=Point(x=0, y=0),
bottom_right=Point(x=100, y=100)
)
print(rect) # Rectangle(top_left=Point(x=0, y=0), bottom_right=Point(x=100, y=100), color=16711680)
from typing import Literal
from cbridge import CStruct
from cbridge import types
class Data(CStruct):
id: types.int32
values: types.Array[types.int8, Literal[4]] # Array of 4 int8 values
name: types.char_ptr
# Create with array data
data = Data(id=1, values=[1, 2, 3, 4], name=b"test")
print(data.values) # [1, 2, 3, 4]
from cbridge import cfunc
from cbridge import types
@cfunc("c") # Bind to libc
def time(t: types.Pointer[types.ctime_t]) -> types.ctime_t: ...
# Call the C function
current_time = time(None)
print(current_time)
import array
from cbridge import CStruct
from cbridge import types
class Point(CStruct):
x: types.int32
y: types.int32
# Create from buffer
buffer = array.array("B", b"\x01\x00\x00\x00\x02\x00\x00\x00")
point = Point.from_buffer(buffer)
print(point) # Point(x=1, y=2)
import ctypes
from cbridge import CStruct
from cbridge import types
class DefaultPackData(CStruct): # 1-byte alignment
a: types.char
b: types.int32
class Pack1Data(CStruct, pack=1): # 1-byte alignment
a: types.char
b: types.int32
print(ctypes.sizeof(DefaultPackData)) # 8 bytes
print(ctypes.sizeof(Pack1Data)) # 5 bytes
from typing import Literal
from cbridge import CStruct
from cbridge import field
from cbridge import types
class Config(CStruct):
name: types.char_ptr
timeout: types.int32 = 30
flags: types.Array[types.int32, Literal[2]] = field(default_factory=lambda: [0, 1])
print(Config(name=b"test")) # Config(name=b'test', timeout=30, flags=[0, 1])
Warning
Python 3.13 and above are currently not supported forward declarations
from cbridge import CStruct
from cbridge import types
from cbridge.types import pointer
class Node(CStruct):
data: types.int32
next: "types.Pointer[Node]"
# Create linked list
node1 = Node(data=1, next=None)
node2 = Node(data=2, next=pointer(node1))
node1.next = pointer(node2)
node = node1
data = []
for _ in range(8):
data.append(node.data)
node = node.next[0] # same as *node.next
assert data == [1, 2, 1, 2, 1, 2, 1, 2]