Simple Python Calls to C++ Programs

Methods for Python to Call C/C++ Programs

Recently, while debugging, I encountered a situation where Python was running very slowly, so I researched methods to embed C++ programs in Python. I am documenting this for future reference.

Generally, calling C/C++ programs from Python can be divided into three steps:

  • 1. Write the C/C++ implementation program. 2. Compile the C/C++ program into a dynamic library. 3. Call the compiled library in Python. There are some differences to note when Python calls C/C++ programs.

1. Python Calls C Functions

Calling C language programs from Python is relatively simple. Compile the C language program and then use the ctypes module in Python to call it.

C Language Source File: called_c.c

// Compilation command gcc -o libpycall.so -shared -fPIC called_c.c
#include<stdio.h>
int foo(int a, int b){<!-- -->
printf("a:%d, b:%d.", &a, &b);
return 0;
}

Enter the following in the command line or terminal:

gcc -o libpycall.so -shared -fPIC called_c.c

This generates the libpycall.so dynamic library file, after which you can call the foo function in Python.Python File: py_call_c.py

import ctypes
dll = ctypes.cdll.LoadLibrary
lib = dll('./libpycall.so') // Path to the library file just generated
lib.foo(1, 3)

The output of running py_call_c.py is:

a:1, b:3

2. Python Calls C++ Classes

Since C++ supports function overloading, when compiling with g++ in C++ mode, the compiler adds extra information to the function names, making it difficult for the ctypes module to find the functions generated by g++. Therefore, to allow g++ to compile in a C language manner so that the function names can be found, you need to wrap the code with the extern keyword.

C++ Source File: cpp_called.cpp

// Python calls C++ (class) dynamic link library
#include <iostream>
using namespace std;

class TestLib
{<!-- -->
    public:
        void display();
        void display(int a);
};
void TestLib::display() {<!-- -->
    cout<<"First display"<<endl;
}

void TestLib::display(int a) {<!-- -->
    cout<<"Second display:"<<a<<endl;
}
extern "C" {<!-- -->
    TestLib obj;
    void display() {<!-- -->
        obj.display();
      }
    void display_int(int a) {<!-- -->
        obj.display(a);
      }
}

Enter the compilation command in the command line or terminal:

g++ -o libpycallcpp.so -shared -fPIC cpp_called.cpp

Explanation of compilation parameters: -fPIC: generates position-independent code suitable for dynamic linking; -L path: indicates to search for library files in the path directory, e.g., -L. indicates the current directory; -I path: indicates to search for header files in the path directory; -o file: specifies the output file as file; -shared: generates a shared library file;

This generates libpycallcpp.so, which can be called in Python.Python File: py_call_c.py

import ctypes
dll = ctypes.cdll.LoadLibrary
lib = dll('./libpycallcpp.so') // Path to the library file just generated
lib.display()
lib.display_int(0)

The output is:

First display
Second display:0

OK, basic functionality is implemented, and advanced calls will be filled in later.

Simple Python Calls to C++ Programs

Leave a Comment