Real Pointers With ctypes
In this lesson, you’ll learn that it is possible to create pointers in Python, but you need to use a bit of C. Sometimes, you may want to improve performance by using a C library in your Python code. For this lesson, you’ll be using the built-in
ctypes module to create real C-style pointers in Python.
00:00 You may run into a scenario where you want to utilize a C library in your Python code, or maybe you want to write a performance-critical function of your application in C, and you still want to be able to access it from Python.
This is where the
ctypes module comes in. The built-in
ctypes module allows you to interface with C libraries. It provides all the necessary Python required to do so, including the ability to create pointers for C functions that require them.
I’m going to write a very small function that will take a pointer to an integer and increment the value it points to by 1. First, I need to tell VIM that I want to edit the current file. So I’ll hit
i to go into insert mode.
Now I can dereference the parameter with the
& (dereference) operator and increment the value by 1. This is a trivial example of a C function, similar to what you saw before, but it should do. Before, we compiled and linked our C code into an executable to run it directly, but in order to use it in Python, we need to compile it into a library.
02:27 This will compile the code into an object file, which is our program written in machine code. We’ll need one more GCC command, which will take that object file and convert it into a dynamic library for use with our Python program.
The name of that library file it outputs will be
libadd1.so, short for “shared objects.” Now that we’ve got a shared object file compiled from our C code, we can fire up a new Python interactive shell and try it out.
./ tells Python to search for the library in the current directory we’re working in. Now that Python knows about the C library we wrote, we can store a reference to the
add_one function in another Python object.
At this point,
add_one acts sort of like a Python function. We can call it with parentheses, and supply arguments, and it will call the underlying C function. But before we do that, we should specify what parameters are required for this C function.
The C function takes an integer pointer. So I’ll say,
ctypes.POINTER and pass in
ctypes.c_int. To show you what this actually did, let me try calling the
add_one function, but with a regular integer, instead of a pointer to one. You see Python raises a
expected LP_c_int, which means integer pointer, but instead, we supplied just a regular integer. Python was able to stop execution before we ever even called the underlying C function, and that’s because we specified the parameter types for this function. To create a pointer to an integer like the function is expecting, we first need to create a C-style integer.
As you can see, this new C integer has a value of 0. Now we can pass a pointer, or a reference, to the
x object in memory. I’ll call
add_one, and then to obtain a pointer to the
x object I’ll use the
Become a Member to join the conversation.