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
>>> from ctypes import * >>> class POINT(Structure): ... _fields_ = [("x", c_int), ... ("y", c_int)] ...
🌐
W3Schools
w3schools.com › python › ref_module_ctypes.asp
Python ctypes Module
import ctypes x = ctypes.c_int(7) x.value += 5 print(x.value) Try it Yourself » · The ctypes module provides C compatible data types and allows calling functions in DLLs/shared libraries.
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
🌐
Turing
turing.com › kb › ctypes-modules-and-their-implementation-in-python
Ctypes Modules and their implementation in Python.
Next, go to the Python file, import the ctypes, and use the CDLL function to load up the shared library file.
🌐
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.
🌐
CodersLegacy
coderslegacy.com › home › python › python ctypes tutorial
Python ctypes Tutorial - CodersLegacy
October 27, 2022 - Do try and use ctypes datatypes as much as possible instead of Python types when writing code which is meant to interact with C. Very few Python types can directly be used with C (without any errors), among-st which two are integers and bytes (byte strings). import ctypes clibrary = ctypes.CDLL('func.so') cstring = ctypes.c_char_p(b"Hello") print("Before:" , cstring.value) clibrary.increment(cstring) print("After: ", cstring.value)
🌐
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
We import the ctypes module in the first line, then the shared library is loaded (usually you would want to include a check for the operating system here and name a dll instead, if running on windows). It is stored in the variable _sum and the functions in this library can be accessed as members ...
🌐
GitHub
github.com › alonho › course › blob › master › doc › ctypes.md
course/doc/ctypes.md at master · alonho/course
This talk is heavily based on the ctypes module's excellent documentation: https://docs.python.org/library/ctypes.html ... It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python. It's part of CPython from 2.5 version. !python >>> import ctypes as c >>> d = c.CDLL("libc.so.6") # /lib/x86_64-linux-gnu/libc.so.6 >>> print d.printf("Hello Linux World\n") Hello Linux World 18
Author: alonho
Find elsewhere
🌐
dbader.org
dbader.org › blog › python-ctypes-tutorial
Extending Python With C Libraries and the “ctypes” Module – dbader.org
September 5, 2017 - Simply calling a function with no parameters is trivial. Once you have loaded the library, the function is just a method of the library object. import ctypes # Load the shared library into c types.
🌐
Readthedocs
scipy-cookbook.readthedocs.io › items › Ctypes.html
Ctypes — SciPy Cookbook documentation - Read the Docs
May 5, 2006 - This allows you to write function wrappers with C linkage on top of a bunch of C++ classes so that you can use them with ctypes. Alternatively, you might prefer to write C code. In [ ]: import numpy as N import ctypes as C _foo = N.ctypeslib.load_library('libfoo', '.') _foo.bar.restype = C.c_int _foo.bar.argtypes = [C.POINTER(C.c_double), C.c_int] def bar(x): return _foo.bar(x.ctypes.data_as(C.POINTER(C.c_double)), len(x)) x = N.random.randn(10) n = bar(x) A ctypes property was recently added to NumPy arrays: In [ ]: In [18]: x = N.random.randn(2,3,4) In [19]: x.ctypes.data Out[19]: c_void_p(1
🌐
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 the next piece of code I will use ctypes to find the system C library and make it available from Python: 1 """Simple example of loading and using the system C library from Python""" 2 import sys, platform 3 import ctypes, ctypes.util 4 5 # Get the path to the system C library 6 if platform.system() == "Windows": 7 path_libc = ctypes.util.find_library("msvcrt") 8 else: 9 path_libc = ctypes.util.find_library("c") 10 11 # Get a handle to the sytem C library 12 try: 13 libc = ctypes.CDLL(path_libc) 14 except OSError: 15 print("Unable to load the system C library") 16 sys.exit() 17 18 print(f'Succesfully loaded the system C library from "{path_libc}"')
🌐
YouTube
youtube.com › coderslegacy
Python ctypes Tutorial - Using C/C++ Functions in Python - YouTube
Python as a Programming Language is slower and less efficient in comparison to languages like C and C++. Writing certain parts of your code in C/C++ can sign...
Published: July 21, 2022
Views: 50K
🌐
Scaler
scaler.com › home › topics › python ctypes module
Python Ctypes Module - Scaler Topics
May 4, 2023 - The Python language offers a number of libraries that utilize C and C++ functions, such as NumPy and OpenCV. With the Python Ctypes library, you can import libraries like this and use their functions.
🌐
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.
🌐
Dalkescientific
dalkescientific.com › writings › NBN › ctypes.html
ctypes
Python 2.5 includes the ctypes module. This is a "foreign function interface" library once available only as a third-party module. A FFI means that Python code can call C functions using only Python.
🌐
Reddit
reddit.com › r/learnpython › using ctypes to import c++ classes
r/learnpython on Reddit: Using ctypes to import C++ classes
December 11, 2016 -

Hi everyone, I have been having trouble getting this to work and its been giving me fits. If anyone can provide insight to what is going wrong that would be extremely helpful.

I am attempting to interface with a device, using python, but the provided files are in C++. My idea was to use ctypes to import the .dll file and then have access to the specific classes used from the .h file. An example of a class from the header file is shown below:

CLASS_DECLSPEC foo(int *var_a, char var_b[]);

The was I was going about it was to first import the .dll file, convert/create the variables used from C++ to python, and rewrite the classes in my Python file. Where I have been having the most trouble is converting the variables. I was trying to make functions that convert C++ data types to python data types, and then use them in my re-written code functions like so:

def type_convert(int):
    i = ctypes.c_int(int)
    return i

def point_convert(p):
    po = ctypes.POINTER(ctypes.c_int(p))
    return po

def array_convert(a):
    arr = ctypes.c_char*8
    char = arr(a)
    return char

Now that these possible data conversions have been written, I can now re-create the C++ class shown above like so:

def new_foo(a, b):
    v_a = point_convert(a)
    v_b = array_convert(b)
    f_oo = imported_lib.foo
    f_oo.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.c_char*8]
    f_oo(v_a, v_b)
    return v_a, v_b

Though, when this is run, nothing works as planned. Is there a fundamental step that I am missing when it comes to ctypes, C++, and python? Thank you so much for taking the time to read my issue, any advice/tip/help would be greatly appreciated.

🌐
NumPy
numpy.org › doc › stable › reference › routines.ctypeslib.html
ctypes foreign function interface (numpy.ctypeslib) — NumPy v2.5 Manual
Converting a ctypes integer array: >>> import ctypes >>> ctypes_array = (ctypes.c_int * 5)(0, 1, 2, 3, 4) >>> np_array = np.ctypeslib.as_array(ctypes_array) >>> np_array array([0, 1, 2, 3, 4], dtype=int32) Converting a ctypes POINTER: >>> import ctypes >>> buffer = (ctypes.c_int * 5)(0, 1, 2, 3, 4) >>> pointer = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_int)) >>> np_array = np.ctypeslib.as_array(pointer, (5,)) >>> np_array array([0, 1, 2, 3, 4], dtype=int32) Go BackOpen In Tab ·
🌐
SciPy
scipy.github.io › old-wiki › pages › Cookbook › Ctypes.html
Cookbook/Ctypes - SciPy wiki dump
This allows you to write function wrappers with C linkage on top of a bunch of C++ classes so that you can use them with ctypes. Alternatively, you might prefer to write C code. 1 import numpy as N 2 import ctypes as C 3 _foo = N.ctypeslib.load_library('libfoo', '.') 4 _foo.bar.restype = C.c_int 5 _foo.bar.argtypes = [C.POINTER(C.c_double), C.c_int] 6 def bar(x): 7 return _foo.bar(x.ctypes.data_as(C.POINTER(C.c_double)), len(x)) 8 x = N.random.randn(10) 9 n = bar(x) A ctypes property was recently added to NumPy arrays: In [18]: x = N.random.randn(2,3,4) In [19]: x.ctypes.data Out[19]: c_void_p