Here's a quick and dirty ctypes tutorial.

First, write your C library. Here's a simple Hello world example:

testlib.c

#include <stdio.h>

void myprint(void);

void myprint()
{
    printf("hello world\n");
}

Now compile it as a shared library (mac fix found here):

$ gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c

# or... for Mac OS X 
$ gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC testlib.c

Then, write a wrapper using ctypes:

testlibwrapper.py

import ctypes

testlib = ctypes.CDLL('/full/path/to/testlib.so')
testlib.myprint()

Now execute it:

$ python testlibwrapper.py

And you should see the output

Hello world
$

If you already have a library in mind, you can skip the non-python part of the tutorial. Make sure ctypes can find the library by putting it in /usr/lib or another standard directory. If you do this, you don't need to specify the full path when writing the wrapper. If you choose not to do this, you must provide the full path of the library when calling ctypes.CDLL().

This isn't the place for a more comprehensive tutorial, but if you ask for help with specific problems on this site, I'm sure the community would help you out.

PS: I'm assuming you're on Linux because you've used ctypes.CDLL('libc.so.6'). If you're on another OS, things might change a little bit (or quite a lot).

Answer from Chinmay Kanchi on Stack Overflow
🌐
Python
docs.python.org › 3 › library › ctypes.html
ctypes — A foreign function library for Python
Source code: Lib/ctypes ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these ...
Top answer
1 of 4
280

Here's a quick and dirty ctypes tutorial.

First, write your C library. Here's a simple Hello world example:

testlib.c

#include <stdio.h>

void myprint(void);

void myprint()
{
    printf("hello world\n");
}

Now compile it as a shared library (mac fix found here):

$ gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c

# or... for Mac OS X 
$ gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC testlib.c

Then, write a wrapper using ctypes:

testlibwrapper.py

import ctypes

testlib = ctypes.CDLL('/full/path/to/testlib.so')
testlib.myprint()

Now execute it:

$ python testlibwrapper.py

And you should see the output

Hello world
$

If you already have a library in mind, you can skip the non-python part of the tutorial. Make sure ctypes can find the library by putting it in /usr/lib or another standard directory. If you do this, you don't need to specify the full path when writing the wrapper. If you choose not to do this, you must provide the full path of the library when calling ctypes.CDLL().

This isn't the place for a more comprehensive tutorial, but if you ask for help with specific problems on this site, I'm sure the community would help you out.

PS: I'm assuming you're on Linux because you've used ctypes.CDLL('libc.so.6'). If you're on another OS, things might change a little bit (or quite a lot).

2 of 4
78

The answer by Chinmay Kanchi is excellent but I wanted an example of a function which passes and returns a variables/arrays to a C++ code. I though I'd include it here in case it is useful to others.

Passing and returning an integer

The C++ code for a function which takes an integer and adds one to the returned value,

extern "C" int add_one(int i)
{
    return i+1;
}

Saved as file test.cpp, note the required extern "C" (this can be removed for C code). This is compiled using g++, with arguments similar to Chinmay Kanchi answer,

g++ -shared -o testlib.so -fPIC test.cpp

The Python code uses load_library from the numpy.ctypeslib assuming the path to the shared library in the same directory as the Python script,

import numpy.ctypeslib as ctl
import ctypes

libname = 'testlib.so'
libdir = './'
lib=ctl.load_library(libname, libdir)

py_add_one = lib.add_one
py_add_one.argtypes = [ctypes.c_int]
value = 5
results = py_add_one(value)
print(results)

This prints 6 as expected.

Passing and printing an array

You can also pass arrays as follows, for a C code to print the element of an array,

extern "C" void print_array(double* array, int N)
{
    for (int i=0; i<N; i++) 
        cout << i << " " << array[i] << endl;
}

which is compiled as before and the imported in the same way. The extra Python code to use this function would then be,

import numpy as np

py_print_array = lib.print_array
py_print_array.argtypes = [ctl.ndpointer(np.float64, 
                                         flags='aligned, c_contiguous'), 
                           ctypes.c_int]
A = np.array([1.4,2.6,3.0], dtype=np.float64)
py_print_array(A, 3)

where we specify the array, the first argument to print_array, as a pointer to a Numpy array of aligned, c_contiguous 64 bit floats and the second argument as an integer which tells the C code the number of elements in the Numpy array. This then printed by the C code as follows,

1.4
2.6
3.0
Discussions

Easy question: can someone explain to me the difference between ctypes and cython?
Ctypes is a module which allows Python code to interface with C code, including the CPython interpreter. Cython is a version of Python (with additional syntax, totally different internals, etc) that can compile certain Python code into pure C code. More on reddit.com
🌐 r/learnpython
9
16
October 1, 2015
Python CTypes
A DLL or shared library is a compiled binary that can be linked into your program to provide some functionality. You can consider it the binary-level equivalent of Python modules. This means that a C program, where variables and functions are native machine-level things, can directly access the contents of a shared library, but a Python program, which runs in an abstracted Python runtime, can not. So to provide access to such libraries, ctypes exists to wrap the C libraries in a Python API, providing Python-level access to the C/machine-level variables and functions contained in the libraries. More on reddit.com
🌐 r/learnprogramming
11
8
June 29, 2014
I fear no man. But that... thing (`ctypes`)... it scares me.
Wow I didnt know there was a way to access the underlying pointers in python More on reddit.com
🌐 r/programminghorror
42
1059
November 28, 2020
🌐
W3Schools
w3schools.com › python › ref_module_ctypes.asp
Python ctypes Module
Python Examples Python Compiler ... Q&A Python Training ... The ctypes module provides C compatible data types and allows calling functions in DLLs/shared libraries....
🌐
Real Python
realpython.com › ref › stdlib › ctypes
ctypes | Python Standard Library – Real Python
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.
🌐
Fz-juelich
pgi-jcns.fz-juelich.de › portal › pages › using-c-from-python.html
Using C from Python: How to create a ctypes wrapper - Scientific IT-Systems
ctypes uses a library that creates functions which follow the platform-dependent calling convention during runtime. Thanks to that, it is also possible to wrap a Python function in a way that it becomes callable from C. When dealing with APIs that include events (e.g.
Find elsewhere
🌐
Readthedocs
scipy-cookbook.readthedocs.io › items › Ctypes.html
Ctypes — SciPy Cookbook documentation
May 5, 2006 - It is included in the standard library for Python 2.5. ctypes allows to call functions exposed from DLLs/shared libraries and has extensive facilities to create, access and manipulate simple and complicated C data types in Python - in other words: wrap libraries in pure Python.
🌐
Yizhang82
yizhang82.dev › python-interop-ctypes
Calling C functions from Python - part 1 - using ctypes | yizhang82’s blog
January 8, 2018 - One of the ways to call C API from Python is to use ctypes module.
🌐
Solarian Programmer
solarianprogrammer.com › 2019 › 07 › 18 › python-using-c-cpp-libraries-ctypes
Python - using C and C++ libraries with ctypes | Solarian Programmer
July 18, 2019 - In this article, I will show you how to use C or C++ dynamic libraries from Python, by using the ctypes module from the Python standard library. ctypes is a foreign function library for Python that provides C compatible data types. Although it is mostly used to consume C and C++ libraries, ...
🌐
Samuelstevens
samuelstevens.me › writing › optimizing-python-code-with-ctypes
Optimizing Python Code with ctypes
ctypes is a module that allows you to communicate with C code from your Python code without using subprocess or similar modules to run another process from the CLI.
🌐
Medium
medium.com › @datasciencefilmmaker › my-god-its-full-of-stars-2-7-accessing-c-structures-in-python-using-ctypes-d75d01d2cb94
My God, It’s Full of Stars (2/7) — Accessing C Structures in Python Using Ctypes | by Data Science Filmmaker | Medium
January 18, 2024 - #### Model structure #### class model(ctypes.Structure): _fields_ = [('evoModel',ctypes.c_int), ('brownDwarfEvol',ctypes.c_int), ('mainSequenceEvol',ctypes.c_int), ('IFMR',ctypes.c_int), ('WDcooling',ctypes.c_int), ('WDatm',ctypes.c_int), ('filterSet',ctypes.c_int), ('numFilts',ctypes.c_int), ('needFS',ctypes.c_int), ('minMass',ctypes.c_double)] #### Model pointer #### modelPtr = ctypes.POINTER(model) #### Star Structure #### class star(ctypes.Structure): _fields_ = [('id',ctypes.c_int), ('obsPhot',ctypes.c_double * FILTS), ('photometry',ctypes.c_double * FILTS), ('variance',ctypes.c_double *
🌐
Oddbit
blog.oddbit.com › post › 2010-08-10-python-ctypes-module
Python ctypes module :: blog.oddbit.com
August 10, 2010 - I just learned about the Python ctypes module, which is a Python module for interfacing with C code. Among other things, ctypes lets you call arbitrary functions in shared libraries.
🌐
PyPI
pypi.org › project › ctypes
ctypes · PyPI
ctypes is a Python package to create and manipulate C data types in Python, and to call functions in dynamic link libraries/shared dlls.
🌐
Python
svn.python.org › projects › ctypes › trunk › ctypes › docs › manual › tutorial.html
ctypes tutorial
None is passed as a C NULL pointer, byte strings and unicode strings are passed as pointer to the memory block that contains their data (char * or wchar_t *). Python integers and Python longs are passed as the platforms default C int type, their value is masked to fit into the C type. Before we move on calling functions with other parameter types, we have to learn more about ctypes data types.
🌐
Chriskrycho
v4.chriskrycho.com › 2015 › ctypes-structures-and-dll-exports.html
Python Enums, ctypes.Structures, and DLL exports · Chris Krycho
May 28, 2015 - You can use ctypes.Structure subclasses natively that way, because the Structure class supplies its from_param classmethod. The same is not true of our custom enum class, though. As the docs put it: If you have defined your own classes which you pass to function calls, you have to implement a from_param() class method for them to be able to use them in the argtypes sequence. The from_param() class method receives the Python object passed to the function call, it should do a typecheck or whatever is needed to make sure this object is acceptable, and then return the object itself, its _as_parameter_ attribute, or whatever you want to pass as the C function argument in this case.
🌐
SageMath
doc.sagemath.org › html › en › thematic_tutorials › numerical_sage › ctypes_examples.html
More complicated ctypes example - Thematic Tutorials
Next consider the following python helper code. from ctypes import * class double_row_element(Structure): pass double_row_element._fields_=[("value",c_double),("col_index",c_int),("next_element",POINTER(double_row_element) )] class double_sparse_matrix(Structure): _fields_=[("nrows",c_int),("ncols",c_int),("nnz",c_int),("rows",POINTER(POINTER(double_row_element)))] double_sparse_pointer=POINTER(double_sparse_matrix) sparse_library=CDLL("/home/jkantor/linked_list_sparse.so") initialize_matrix=sparse_library.initialize_matrix initialize_matrix.restype=double_sparse_pointer set_value=sparse_library.set_value get_value=sparse_library.get_value get_value.restype=c_double free_matrix=sparse_library.free_matrix
🌐
Reddit
reddit.com › r/programminghorror › i fear no man. but that... thing (`ctypes`)... it scares me.
r/programminghorror on Reddit: I fear no man. But that... thing (`ctypes`)... it scares me.
November 28, 2020 - ctypes is part of the standard library in CPython. Its not really recommended use to do this, though. Its meant to be used with external C libs. ... If you're the adventurous type, there are some pretty fun talks out there on how deep you can ...
🌐
Pendancer
python.pendancer.com › advanced › ctypes.html
CTypes and Structures - Python
CTypes provide C compatible data types and allow function calls from DLLs or shared libraries without having to write custom C extensions for every operation. So we can access the functionality of a C library from the safety and comfort of the Python Standard Library.