or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-system.mdc-cpp-interoperability.mdcommand-line-tools.mdcore-language.mddebugging-profiling.mdimport-system.mdindex.mdipython-integration.md

c-cpp-interoperability.mddocs/

0

# C/C++ Interoperability

1

2

Cython provides extensive capabilities for interfacing with C and C++ libraries, enabling seamless integration between Python and compiled code. This includes standard library bindings, external library interfaces, and tools for wrapping existing C/C++ codebases.

3

4

## Capabilities

5

6

### Python C API Bindings

7

8

Pre-defined declarations for the Python C API, enabling direct access to Python internals from Cython code.

9

10

```python { .api }

11

# Available cpython modules (cimport from cpython.*)

12

from cpython.object cimport PyObject, Py_INCREF, Py_DECREF

13

from cpython.list cimport PyList_New, PyList_Append, PyList_GET_ITEM

14

from cpython.dict cimport PyDict_New, PyDict_SetItem, PyDict_GetItem

15

from cpython.tuple cimport PyTuple_New, PyTuple_SET_ITEM, PyTuple_GET_ITEM

16

from cpython.string cimport PyString_AsString, PyString_FromString

17

from cpython.unicode cimport PyUnicode_AsUTF8String, PyUnicode_FromString

18

from cpython.bytes cimport PyBytes_AsString, PyBytes_FromString

19

from cpython.buffer cimport Py_buffer, PyBuffer_Release

20

from cpython.memoryview cimport PyMemoryView_FromBuffer

21

from cpython.complex cimport PyComplex_RealAsDouble, PyComplex_ImagAsDouble

22

```

23

24

### Standard C Library Bindings

25

26

Declarations for standard C library functions and constants.

27

28

```python { .api }

29

# Available libc modules (cimport from libc.*)

30

from libc.stdio cimport printf, fprintf, fopen, fclose, FILE

31

from libc.stdlib cimport malloc, free, calloc, realloc, atoi, atof

32

from libc.string cimport strlen, strcpy, strcat, strcmp, memcpy, memset

33

from libc.math cimport sin, cos, tan, sqrt, pow, log, exp, M_PI

34

from libc.time cimport time_t, clock_t, time, clock, difftime

35

from libc.errno cimport errno, ENOENT, ENOMEM, EINVAL

36

```

37

38

### C++ Standard Library Bindings

39

40

Declarations for C++ standard library containers and utilities.

41

42

```python { .api }

43

# Available libcpp modules (cimport from libcpp.*)

44

from libcpp.vector cimport vector

45

from libcpp.string cimport string

46

from libcpp.map cimport map, pair

47

from libcpp.set cimport set, unordered_set

48

from libcpp.deque cimport deque

49

from libcpp.list cimport list as cpp_list

50

from libcpp.queue cimport queue, priority_queue

51

from libcpp.stack cimport stack

52

from libcpp.algorithm cimport sort, find, binary_search

53

from libcpp.iterator cimport back_inserter

54

from libcpp.memory cimport shared_ptr, unique_ptr, make_shared

55

```

56

57

### NumPy Integration

58

59

Specialized declarations for efficient NumPy array operations and C API access.

60

61

```python { .api }

62

# NumPy integration (cimport numpy as cnp)

63

import numpy as np

64

cimport numpy as cnp

65

66

# Core array types and functions

67

cnp.ndarray, cnp.dtype, cnp.flatiter

68

cnp.int8_t, cnp.int16_t, cnp.int32_t, cnp.int64_t

69

cnp.uint8_t, cnp.uint16_t, cnp.uint32_t, cnp.uint64_t

70

cnp.float32_t, cnp.float64_t, cnp.complex64_t, cnp.complex128_t

71

72

# Memory views for efficient array access

73

cnp.int_t[:], cnp.double_t[:, :], cnp.complex_t[:, :, :]

74

```

75

76

### POSIX System Interfaces

77

78

POSIX API declarations for system-level programming.

79

80

```python { .api }

81

# Available posix modules (cimport from posix.*)

82

from posix.unistd cimport getpid, getuid, getgid, sleep, usleep

83

from posix.fcntl cimport open, O_RDONLY, O_WRONLY, O_CREAT

84

from posix.stat cimport stat, S_ISREG, S_ISDIR

85

from posix.time cimport timespec, nanosleep

86

from posix.signal cimport kill, SIGTERM, SIGKILL

87

```

88

89

### OpenMP Parallel Programming

90

91

OpenMP support for parallel computing and multi-threading.

92

93

```python { .api }

94

from cython.parallel cimport prange, parallel, threadid

95

from openmp cimport omp_get_num_threads, omp_get_thread_num, omp_set_num_threads

96

```

97

98

### External Library Declaration

99

100

Templates and patterns for declaring external C/C++ libraries.

101

102

```python { .api }

103

# External C library declaration template

104

cdef extern from "my_library.h":

105

ctypedef struct my_struct:

106

int field1

107

double field2

108

109

int my_function(int arg1, double arg2)

110

void* my_malloc(size_t size)

111

void my_free(void* ptr)

112

113

# Constants and macros

114

enum:

115

MY_CONSTANT = 42

116

117

cdef int MY_MACRO_VALUE

118

119

# External C++ library declaration template

120

cdef extern from "my_cpp_library.hpp" namespace "MyNamespace":

121

cppclass MyClass:

122

MyClass() except +

123

MyClass(int value) except +

124

int get_value()

125

void set_value(int value)

126

127

cppclass MyTemplate[T]:

128

MyTemplate() except +

129

void push_back(T& item)

130

T& operator[](size_t index)

131

```

132

133

## Usage Examples

134

135

### Python C API Direct Access

136

137

```cython

138

from cpython.object cimport PyObject, Py_INCREF, Py_DECREF

139

from cpython.list cimport PyList_New, PyList_Append

140

141

def create_optimized_list(items):

142

"""Create list using Python C API directly."""

143

cdef PyObject* py_list = PyList_New(0)

144

cdef PyObject* item

145

146

for python_item in items:

147

item = <PyObject*>python_item

148

Py_INCREF(item)

149

PyList_Append(py_list, item)

150

151

return <object>py_list

152

```

153

154

### Standard C Library Usage

155

156

```cython

157

from libc.stdlib cimport malloc, free

158

from libc.string cimport strcpy, strlen

159

from libc.stdio cimport printf

160

161

def c_string_operations(str python_string):

162

"""Demonstrate C string operations."""

163

cdef bytes byte_string = python_string.encode('utf-8')

164

cdef char* c_string = byte_string

165

cdef size_t length = strlen(c_string)

166

167

# Allocate C memory

168

cdef char* buffer = <char*>malloc(length + 1)

169

if buffer == NULL:

170

raise MemoryError("Failed to allocate memory")

171

172

try:

173

# Copy string

174

strcpy(buffer, c_string)

175

printf("C string: %s (length: %zu)\n", buffer, length)

176

177

return buffer[:length].decode('utf-8')

178

finally:

179

free(buffer)

180

```

181

182

### C++ Standard Library Integration

183

184

```cython

185

from libcpp.vector cimport vector

186

from libcpp.string cimport string

187

from libcpp.map cimport map, pair

188

from libcpp.algorithm cimport sort

189

190

def cpp_containers_demo():

191

"""Demonstrate C++ container usage."""

192

# Vector operations

193

cdef vector[int] vec

194

cdef int i

195

196

for i in range(10):

197

vec.push_back(i * i)

198

199

# Sort vector

200

sort(vec.begin(), vec.end())

201

202

# Map operations

203

cdef map[string, int] word_count

204

cdef vector[string] words = [b"hello", b"world", b"hello"]

205

206

for word in words:

207

word_count[word] += 1

208

209

# Convert to Python dict

210

result = {}

211

cdef map[string, int].iterator it = word_count.begin()

212

while it != word_count.end():

213

result[it.first.decode('utf-8')] = it.second

214

it += 1

215

216

return list(vec), result

217

```

218

219

### NumPy Array Optimization

220

221

```cython

222

import numpy as np

223

cimport numpy as cnp

224

225

def fast_array_operations(cnp.double_t[:, :] matrix):

226

"""Optimized matrix operations using NumPy C API."""

227

cdef int rows = matrix.shape[0]

228

cdef int cols = matrix.shape[1]

229

cdef int i, j

230

cdef double sum_val = 0.0

231

232

# Direct memory access without Python overhead

233

for i in range(rows):

234

for j in range(cols):

235

sum_val += matrix[i, j] * matrix[i, j]

236

237

return np.sqrt(sum_val)

238

239

def create_array_from_c_data(int size):

240

"""Create NumPy array from C data."""

241

cdef cnp.npy_intp shape[1]

242

shape[0] = <cnp.npy_intp>size

243

244

# Allocate array

245

cdef cnp.ndarray result = cnp.PyArray_EMPTY(1, shape, cnp.NPY_DOUBLE, 0)

246

cdef double[:] result_view = result

247

248

cdef int i

249

for i in range(size):

250

result_view[i] = i * 0.5

251

252

return result

253

```

254

255

### External C Library Wrapping

256

257

```cython

258

# my_library_wrapper.pyx

259

cdef extern from "external_lib.h":

260

ctypedef struct Point:

261

double x

262

double y

263

264

Point* create_point(double x, double y)

265

void destroy_point(Point* p)

266

double distance(Point* p1, Point* p2)

267

void move_point(Point* p, double dx, double dy)

268

269

cdef class PyPoint:

270

"""Python wrapper for C Point struct."""

271

cdef Point* _c_point

272

273

def __cinit__(self, double x, double y):

274

self._c_point = create_point(x, y)

275

if self._c_point == NULL:

276

raise MemoryError("Failed to create point")

277

278

def __dealloc__(self):

279

if self._c_point != NULL:

280

destroy_point(self._c_point)

281

282

property x:

283

def __get__(self):

284

return self._c_point.x

285

def __set__(self, double value):

286

self._c_point.x = value

287

288

property y:

289

def __get__(self):

290

return self._c_point.y

291

def __set__(self, double value):

292

self._c_point.y = value

293

294

def distance_to(self, PyPoint other):

295

return distance(self._c_point, other._c_point)

296

297

def move(self, double dx, double dy):

298

move_point(self._c_point, dx, dy)

299

```

300

301

### C++ Class Wrapping

302

303

```cython

304

# cpp_wrapper.pyx

305

from libcpp.string cimport string

306

from libcpp.vector cimport vector

307

308

cdef extern from "MyClass.hpp":

309

cppclass CppClass:

310

CppClass() except +

311

CppClass(string name) except +

312

313

string get_name()

314

void set_name(string name)

315

void add_value(double value)

316

vector[double] get_values()

317

double compute_average()

318

319

cdef class PyCppClass:

320

"""Python wrapper for C++ class."""

321

cdef CppClass* _cpp_obj

322

323

def __cinit__(self, str name=""):

324

cdef string cpp_name = name.encode('utf-8')

325

self._cpp_obj = new CppClass(cpp_name)

326

327

def __dealloc__(self):

328

del self._cpp_obj

329

330

@property

331

def name(self):

332

return self._cpp_obj.get_name().decode('utf-8')

333

334

@name.setter

335

def name(self, str value):

336

cdef string cpp_name = value.encode('utf-8')

337

self._cpp_obj.set_name(cpp_name)

338

339

def add_value(self, double value):

340

self._cpp_obj.add_value(value)

341

342

def get_values(self):

343

cdef vector[double] cpp_values = self._cpp_obj.get_values()

344

return [cpp_values[i] for i in range(cpp_values.size())]

345

346

def compute_average(self):

347

return self._cpp_obj.compute_average()

348

```

349

350

### OpenMP Parallel Computing

351

352

```cython

353

from cython.parallel cimport prange, parallel

354

from openmp cimport omp_get_thread_num, omp_set_num_threads

355

import numpy as np

356

cimport numpy as cnp

357

358

def parallel_sum(cnp.double_t[:] array, int num_threads=4):

359

"""Parallel array summation using OpenMP."""

360

omp_set_num_threads(num_threads)

361

362

cdef int n = array.shape[0]

363

cdef double total = 0.0

364

cdef int i

365

366

with nogil, parallel():

367

for i in prange(n, schedule='static'):

368

total += array[i]

369

370

return total

371

372

def parallel_matrix_multiply(cnp.double_t[:, :] A, cnp.double_t[:, :] B):

373

"""Parallel matrix multiplication."""

374

cdef int M = A.shape[0]

375

cdef int N = A.shape[1]

376

cdef int P = B.shape[1]

377

378

cdef cnp.double_t[:, :] C = np.zeros((M, P), dtype=np.float64)

379

380

cdef int i, j, k

381

with nogil, parallel():

382

for i in prange(M, schedule='dynamic'):

383

for j in range(P):

384

for k in range(N):

385

C[i, j] += A[i, k] * B[k, j]

386

387

return np.asarray(C)

388

```

389

390

### Advanced Memory Management

391

392

```cython

393

from cpython.mem cimport PyMem_Malloc, PyMem_Free

394

from libc.string cimport memcpy

395

396

cdef class ManagedBuffer:

397

"""Memory-managed buffer with C and Python integration."""

398

cdef void* _buffer

399

cdef size_t _size

400

cdef bint _owns_memory

401

402

def __cinit__(self, size_t size):

403

self._size = size

404

self._buffer = PyMem_Malloc(size)

405

self._owns_memory = True

406

407

if self._buffer == NULL:

408

raise MemoryError("Failed to allocate buffer")

409

410

def __dealloc__(self):

411

if self._owns_memory and self._buffer != NULL:

412

PyMem_Free(self._buffer)

413

414

def copy_from_array(self, cnp.uint8_t[:] source):

415

"""Copy data from NumPy array to C buffer."""

416

if source.shape[0] > self._size:

417

raise ValueError("Source array too large")

418

419

memcpy(self._buffer, &source[0], source.shape[0])

420

421

def as_array(self):

422

"""Return buffer contents as NumPy array."""

423

cdef cnp.npy_intp shape[1]

424

shape[0] = <cnp.npy_intp>self._size

425

426

# Create array that shares memory (no copy)

427

return cnp.PyArray_SimpleNewFromData(

428

1, shape, cnp.NPY_UINT8, self._buffer

429

)

430

```

431

432

The C/C++ interoperability features in Cython enable seamless integration with existing libraries, high-performance computing frameworks, and system-level programming interfaces, making it an ideal bridge between Python and compiled code.