Calling C++ functions in python
- Call without parameters
- Single variable incoming and returning calls
- Numpy array passing in and return calls
- c++ class call
- Isn’t it nice to write in python? Is it so complicated to call C++?
1. Call without parameters
To call a C++ function with no parameters and no return in python, the specific usage is as follows:
Writing form of C++API function:
#include<iostream>
#include<string>
using namespace std;
extern "C"{
int hehe(void){
cout << "hello world!" << endl;
return 0;
}
}
Generate the .so dynamic link library from the written .cpp file and execute the following command on the ubuntu command line:
g++ -o xxx.os -shared -fPIC xxx.cpp
You can see the generated xxx.so file under the corresponding file.
Python calls the generated dynamic link library:
import ctypes
dll = ctypes.cdll.LoadLibrary('./doc.so')
dll.hehe()
Running the python file gets the following results:
2. Single variable incoming and returning calls
In the C++ function, the python program needs to pass in a single variable parameter, integer, floating point or character type. The corresponding relationship is as follows:
The C++ program is as follows:
#include <iostream>
#include <string>
using namespace std;
extern "C"{
int hehe(int a){
int i = 0;
i = a * a;
return i;
}
}
The program using python is:
import ctypes
dll = ctypes.cdll.LoadLibrary('./doc.so')
a = 23
a2 = dll.hehe(a)
print(a2)
operation result:
3. Numpy array incoming and returning calls
Passing the numpy array into the C++ function is very different from the previous method of passing in the variable:
1. First, process the numpy array to obtain the pointer of the storage location (remember that the numpy array memory must be continuous)
2. Pass the obtained pointer to the corresponding C++ function.
In this process, a problem will arise. For example, the numpy array is a two-dimensional matrix, but the parameter obtained by C++ is just a pointer, so we need to have a calculation. Convert the position coordinates in the multi-dimensional space into pointer subscripts in one dimension: For example:
Suppose there is a multi-dimensional matrix MxNxH, and the actual storage order in the memory is H elements in the first row and first column - first H elements in the second column of the row. . . By analogy
3. For the return of the incoming pointer, because the actual physical address is passed in, the changes to the data in the C++ function will also be correspondingly changed in Python.
The specific C++ program is:
#include <iostream>
#include <string>
using namespace std;
extern "C"{
void hehe(int* a,int rows,int cols){
int row,col;
for(row = 0;row < rows; row++)
{
for(col = 0;col < cols;col++)
{
int ind = row * cols + col;
a[ind] = a[ind]* a[ind];
}
}
}
}
The corresponding python file is:
import ctypes
import numpy as np
dll = ctypes.cdll.LoadLibrary('./doc.so')
a = np.array([[1,2,3],[2,3,4],[3,4,5]],dtype=np.int32)
p = a.ctypes.data_as(ctypes.POINTER(ctypes.c_int32))
print(a)
dll.hehe(p,3,3)
print(a)
The result of running the python file is:
4. Numpy array incoming and returning calls
class test{
public:
void test(void);
};
extern "C"{
test t;
void test(void)
{
t.test();
}
}
void test::test(void)
{
cout << "hello world!" << endl;
}
Isn’t it nice to write in python? Is it so complicated to call C++?
I don’t know the specific difference between the two in other aspects, but in terms of processing speed, I did a small experiment. I believe that after reading this, there will be no similar questions. The content of the experiment is: for a 512x512x10 all-one matrix, perform the operation of adding 1 to all elements. Use python and C++ to perform the operation to see how long it takes.
Specific code:
#include<iostream>
#include<string>
using namespace std;
extern "C"{
void hehe(int* p ,int row,int col,int channel){
int h,w,c;
for(h = 0;h < row;h++)
{
for(w = 0;w < col;w++)
{
for(c = 0;c < channel;c++)
{
int ind = h*(col * channel) + w * channel + c;
p[ind] = p[ind] + 1;
}
}
}
}
}#include<iostream>
#include<string>
using namespace std;
extern "C"{
void hehe(int* p ,int row,int col,int channel){
int h,w,c;
for(h = 0;h < row;h++)
{
for(w = 0;w < col;w++)
{
for(c = 0;c < channel;c++)
{
int ind = h*(col * channel) + w * channel + c;
p[ind] = p[ind] + 1;
}
}
}
}
}
import ctypes as ct
import numpy as np
import time
def add1(m,h,w,c):
for row in range(h):
for col in range(w):
for channel in range(c):
m[row][col][channel] += 1
ll = ct.cdll.LoadLibrary("./test.so")
m = np.ones([10,512,512],np.int32)
print(m.shape)
h,w,c = m.shape[:3]
p = m.ctypes.data_as(ct.POINTER(ct.c_int32))
t1 = time.time()
ll.hehe(p,h,w,c)
print('c++ time:',time.time()-t1)
t2 = time.time()
add1(m,h,w,c)
print('python time:',time.time()-t2)
Running results (open your eyes to see clearly):