Calling C Functions from Python [Step by Step Procedure]

Calling C Functions from Python [Step by Step Procedure]

Here, in this tutorial, I am going to tutor you a simple Python wrapper for C library. And how to call C functions from Python?

Before beginning this, let’s see…

Why do we need of Calling C Functions from Python?

Till now I have talked about many plus points about Python.

But…

There is One of the major disadvantages of Python – its execution speed. ūüôĀ ¬†Python is slower than many of the competitive programming language like C, Java…

C and CPP is a very standard programming language. And there are so many libraries already available in C.

To enhance the speed of the Python and to make the reuse of existing C libraries, the concept of calling C functions from Python is useful.

So there are two advantages of using C libraries (or C functions):

  • As the library is compiled from C programming, it increases the spread of execution. (C program runs faster than Python program.)
  • There are many C libraries are already build. Reusing existing C libraries saves time and resource.

In fact, there are many Python inbuilt standard libraries are written in C. You may not have noticed it, but many times when you call inbuilt function, it executes C function internally.

So coming to our coding part…

How to create these C libraries?

In this tutorial, I am going to tell you, how to compile a C program to create a library and step by step procedure for calling C functions from Python code.

Creating C library and Calling C Functions from Python

Steps…

  1. Write a C program with a function definition
  2. Write a C program header file with all function declaration
  3. Create a C library that can be used in Python
  4. Calling C functions from Python program

To understand this tutorial, we will create an arithmetic application where all the arithmetic definition are written in C. And we will write a wrapper using Python called calcithat will call the function written in C program.

Let’s begin…

Step 1: Write a C program with functions definition

First of all, write a simple C program with functions definition.

Even if you know the basics of C and C++ programming, you can write the function in C that performs the basic arithmetic operations.

Following is code in C.

#include <stdio.h>
#include <stdlib.h>
#include "arithmatic.h"

void connect()
{
    printf("Connected to C extension...\n");
}

//return random value in range of 0-50
int randNum()
{
    int nRand = rand() % 50; 
    return nRand;
}

//add two number and return value
int addNum(int a, int b)
{
    int nAdd = a + b;
    return nAdd;
}

Note: There is no function main() in the above program. There are only function definitions that we are going to call them from the Python program.

Save the above program as arithmatic.c.

Step 2: Write a C Program Header File with all Function Declaration

We may have noticed in above C program as we have included header file as arithmatic.h.

void connect();
int randNum();
int addNum(int a, int b);

This header file contains declarations of all the arithmetic functions.

Save the file as aithmatic.h. in the same directory.

Step 3: Create a C library that can be used in Python

You need gcc compiler to compile C program.

To use that C function in Python you need to compile and generate the shared object.

Now Compile C program Using gcc Compiler:

gcc -c -fPIC arithmatic.c -o arithmatic.o

It will generate .o file. Run below command to get the shared object .so file from .o.

gcc arithmatic.o -shared -o libcalci.so

It will create the file libcalci.so.

Another way using the Single Command:

We are only interested in file .so (shared object). So, we can skip creating .o file.

You can merge above two commands into one, that will give you shared object without getting .o object file.

gcc -shared -o libcalci.so -fPIC arithmatic.c

After running this command you see the file libcalci.so is generated in the current directory.

Backend C library (libcalci.so) is ready to use. We can import it into our Python program to use it.

Note: You need to generate shared object .so file for Linux, OS X, etc. For the Window OS,  you need to generate .dll file.

Step 4: Calling C Functions from Python Program

As like Python programming, writing wrapper is easier than it sounds.

To call C functions from Python wrapper, you need to import ctypes foreign function library in Python code.

(You can read more about this library on Python official document.)

Load .so file that we have created in the previous step by creating an instance of CDLL. Just call to its constructor function CDLL(). It returns the object variable (says libCalc).

Now, with this object variable, you can call and pass input parameters to C functions just like calling normal Python class functions.

Here is a simple code.

from ctypes import *
libCalc = CDLL("./libcalci.so")

#call C function to check connection
libCalc.connect() 

#calling randNum() C function
#it returns random number
varRand = libCalc.randNum()
print "Random Number:", varRand, type(varRand)

#calling addNum() C function
#it returns addition of two numbers
varAdd = libCalc.addNum(20,30)
print "Addition : ", varAdd

Output:

Connected to C extension...
Random Number: 27 <type 'int'>
Addition: 50

In the program, we used function type() to identify the return data type of the C function’s variable.

This is all about creating C library and calling C functions with Python. If you have any question or doubt, write in a comment. I do reply to all comments.

Some points to Acknowledge:

  • We are using ctype native Python module to load the shared library.
  • The ctype Python module is available from 2.5 Python version. So, just ensure you have the latest version installed on your system
  • All these commands and programs in this tutorial¬†are run on Ubuntu Linux system. And it will work for all other systems as well.

Before learning Python, I learned C programming. Whenever I require, many times I reuse existing C programs (those are written earlier on my system) in Python. It saves me lots of time. Even, it is the useful approach of writing your own C library and executing complex logic faster in C functions.

Hope you enjoy this tutorial.

If you want to be the expert Python programmer, you can follow my complete Python tutorial for FREE.

Happy Programming!

44 Comments

      1. Hey Aniruddha,

        Have you ever tried writing a python wrapper to create a C file and add instructions into the C file using python scripting? and later compile it in the end?

        1. This is definitely doable and as simple as writing to files like any other in Python just with a .c extension and then using a shell call to compile said files.

  1. Can I call C program from python that uses wiringPi to write to an LCD 20×2 through an MCP23017 chip? I am using the LCD 20×2 to display the date and time and CPU temperature of a raspberry pi.

    Thank you

    1. Many have done similar projects for Micropython, a python distribution for microcontrollers. Just google for it. surprisingly, these projects have made use of Python for raspberry pi and Arduino projects source code.

      This article really helped me understand C. Thanks, Aniruddha Chaudhari.

  2. Hi,

    Is it possible to call Scala code from python without pyspark like above code (calling c code from python)? Is it possible to call Scala code from python like above?

  3. Hey, how can I use a C function to create a new column in a pandas data frame using “apply”?

    1. C functions are used to implement some algorithms and logic. It is difficult to retain the Python data types in C.

      In your case, you can write C function that manipulates and creates the desired array. Return this array data to the Python and then append that array to Pandas data frame as a new column in Python.

  4. Your page /calling-c-functions-from-python was the only internet source that worked right for me.

    BTW change gcc hello.o to gcc arithmetic.o, otherwise it fails.

  5. Hello!
    I have a problem with the C function parameters.
    When I set a string parameter in a C function through python, it reads only the first character of the string. I’m wondering if it’s a type error because the string type in python is different from C.
    how can I fix this? Is there a way to pass a string that is compatible with C?

    note: this problem occurs only when I use python3.7, if I use python2.7 interpreter, it works fine.

    note2: sorry about my English. I’m Brazilian xD

    1. Hi Cassio,

      As your code is working with Python2.7 and not working with Python 3.7, there is a change in string implementation in both the versions.

      By default string in Python 2 is ASCII type whereas string in Python 3 is Unicode. Try typecasting the string in your code.

      Please let me know if this works for you.

  6. How to access the char array returned from C program, as of now the program is returning the memory address of the pointer.

    1. You can not do it directly. You can execute a compiled C program (.exe file) from the Python program using a subprocess module by running the executable file using subprocess.open() method in Linux.

    1. Hi Shaleen.

      This will be tricky. Whenever we return a string or double array, the function does not return actual value, but it returns a pointer to these data objects.

      You have to explicitly save these arguments in the dynamic memory and then return the reference from C to Python.

  7. Hi,

    Actually I am using dalsa teledyne camera which has a default .so called libGevapi.so file. I am trying to access the functions of that library from python using ctypes method as shown by you. The functions can be accessed but it is not returning correct results.
    Jst, for example, there is a function called GevDevicecount which returns no. of devices connected to the system. When I am directly running the C code to access the function it returns 2 devices connected. But when I access the same function from python using ctypes method it returns 0. where 2 is the correct result.

    can you help me where the issue is?

    1. Hi Pooja. Looks like there is a mismatch of the return data type. Try with different expected return values (says 3, 4), if it is still returning 0, most probably a problem is with the expected data type of the return variable.

  8. Hey, very helpful tutorial, thanks so much! My question is, how do I use Python to run a C function that normally needs to be run with sudo?

    1. If the user running the Python program has root privilege, you can run the C function (even it needs to be run with Sudo). Another way, you can grant the executable permission to the C program for the normal user.

  9. This step by step tutorial is a neat solution to exactly the problem I was facing. Very concise and clear. Thank you! Kind regards, Mathias from Germany.

  10. Excellent tutorial, congratulation! I am just looking for a (and can’t find any) suitable makefile, in which I would just list all .o files (created from their c source files) and finally would get their .so files using the same names as the original C source files. Do you have some ideas? Thanks in advance for your reply.

    Regards,
    Peter

  11. Thanks for a prompt reply. Well, I have to admit that I am a little bit “rusty” with the makefiles as I haven’t used them for the last 15 years (a side efect of using MS Visual Studio ūüôā ), but yes, there is no problem to write and execute something like:

    LibFun1 : Fun1.c Fun1.h
        gcc -o LibFun1 -shared Fun1.c
    

    But imagine, I want to have several other pairs of Funx.c and Funx.h in the same folder and to create the shared library files of all of them. If I write the makefile like:

    LibFun1 : Fun1.c Fun1.h
        gcc -o LibFun1 -shared Fun1.c
    
    LibFun2 : Fun2.c Fun2.h
        gcc -o LibFun2 -shared Fun2.c
    

    only the first command line (for LibFun1) will be executed. So, is there a way to create a makefile such a way that all shared library files will be created with just one “make” call?

    And I have a second question regarding a shared library function, which would return more than just a single value. For example, in your tutorial the Connect() function will print the text into the C “console”, but I want to see it in the Python “window”. So, how can the Connect() function return an entire string to the Python variable?

    Thanks in advance for your reply!

    Regards,
    Peter

  12. Hi Aniruddha,
    I made further experiments (well, on the Raspberry Pi, where I am doing all these experiments), and I found out that to return a string (or any aggregated variable) from a C function to Python program, you can do so only via a reference type function argument. Return won’t work! For example, the code which normally work in a C program:

    char st[] = "Hello";
    
    char *RetStr(void)
    {
         // char st[] = "Hello";
         return st;
    }
    
    void main()
    {
         printf("Remote greeting: %s", RetStr());
    }
    

    will not work with the Python. Instead of the string, the RetStr() function will return a number, apparently the st address. The only way (well, based on my limited observations) how to return a string is as follows:

    char st[] = "Hello";
    
    void RetStr(char s[])
    {
         strcpy(s, st);
    }
    

    and in the Python program to call this C function as:

    txt = ""                "
    
    libClib.RetStr(txt)
    

    And the txt has to be long enough to receive the entire text string from C. If txt is defined like txt = "", nothing will be copied. This surprises me, as I expected that the RetStr() function would create another txt object with the length and content depending only on what RetStr() provides.

    Regards,
    Peter

  13. Hi Aniruddha,
    As sitting at home due to both, pandemic and bad weather (imagine, we’ve got snow again in Ottawa, Canada) I have a lot of time to play with the Raspberry Pi, so I found out how to properly retrieve a string value returned by a C function as a pointer to char.
    Here is the C library function:

    char st[] = "Connection to library.";
    
    char *Connect(void)
    {
         return st;
    }
    

    And here is the Python code:

    from ctypes import *
    libCalc = CDLL("./libcalci.so")
     
    #call C function to check connection
    libCalc.Connect.restype = c_char_p    # instruct Python that given function returns char*
    print libCalc.Connect() 
    

    Regards,
    Peter

    1. Hi Peter,

      Yeah, time is not really good.I’m really impressed the way you are utilizing this time at the best.

      At last, you featured it out the passing string. Awesome!

      Stay Home and Stay Safe, Peter!

      And keep sharing your findings with us.

      Regards,
      Ani

  14. I cannot get my C code to return a string. Is there a secret to it?
    Is there something special to be done on the python 3 side?

    1. Not sure what exactly is the problem. Just to give you heads up, in Python 2, string type is ASCII. And in Python 3, string type is Unicode. Check if you have a mismatch with the string formating.

  15. suppose I have a c code that compiles using external libraries (along with paths), in the following way:

    clang -Xpreprocessor -I/opt/local/include/libomp -L/opt/local/lib/libomp -lomp -w -o SpecFit SpecFit.c -lgsl  -lm

    then in your step 3, should I be adding these extra arguments when making the shared object (as below)?

    gcc -shared -o SpecFit.so -fPIC SpecFit.c -Xpreprocessor -I/opt/local/include/libomp -L/opt/local/lib/libomp -lomp -w -lgsl  -lm

Leave a Reply

Your email address will not be published. Required fields are marked *