python中调用C++函数

  • 无参调用
  • 单变量传入与返回调用
  • numpy数组传入与返回调用
  • c++类调用
  • 用python写不香吗?还这么复杂调用C++?
一、 无参调用

在python中调用无参数和无返回的C++函数,具体的使用方式如下:
C++API函数的编写形式:

#include<iostream>
#include<string>
using namespace std;

extern "C"{
	int hehe(void){
		cout << "hello world!" << endl;
		return 0;
	}
}

将编写的.cpp文件生成.so动态链接库在ubuntu命令行中执行如下命令:

g++ -o xxx.os -shared -fPIC xxx.cpp

在相应的文件下就可看到生成的xxx.so文件。
python调用生成的动态链接库:

import ctypes

dll = ctypes.cdll.LoadLibrary('./doc.so')
dll.hehe()

运行python文件得到如下结果:

python调用c 程序 python调用c++_numpy

二、单变量传入与返回调用

在C++函数中需要python程序传入一个单变量的参数,整形,浮点型或者字符型。其中对应关系如下:

python调用c 程序 python调用c++_numpy_02

C++的程序如下:

#include <iostream>
#include <string>

using namespace std;

extern "C"{
    int hehe(int a){
        int i = 0;
        i = a * a;
        return i;
    }
}

对用python的程序为:

import ctypes

dll = ctypes.cdll.LoadLibrary('./doc.so')
a = 23
a2 = dll.hehe(a)
print(a2)

运行结果:

python调用c 程序 python调用c++_#include_03

三、numpy数组传入与返回调用

对于numpy数组传入C++函数与之前的但变量传入大不相同:
1、首先对numpy数组处理得到存储位置的指针(切记numpy数组内存一定要连续)
2、将得到的指针传递给对应的C++函数。
在这个过程中,会有一个问题出现,比如numpy数组为一个二维的矩阵,但C++得到参数只是一个指针,所以我们要有一个计算。将多维空间中的位置坐标转换为一维中的指针下标:举例如下:
假设有一个多维的矩阵MxNxH,转换为内存中的实际存储顺序为第一行第一列的H个元素-第一行第二列的H个元素。。。依次类推
3、对于传入指针的返回,因为传入的是实际物理地址,所以在C++函数中对数据的改变,在python对应的也会发生相应的改变。
具体C++程序为:

#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];
            }
        }
        
    }
}

与之相对应的python文件为:

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)

运行python文件得到的结果为:

python调用c 程序 python调用c++_numpy_04

四、numpy数组传入与返回调用
class test{
	public:
		void test(void);
};

extern "C"{
	test t;
	void test(void)
	{
		t.test();
	}
}
void test::test(void)
{
	cout << "hello world!" << endl;
}
用python写不香吗?还这么复杂调用C++?

别的方面具体不不清楚两者的区别,但是就从处理速度来说,我做了一个小实验,相信看完之后就没有类似的疑问了。实验的内容为:对于一个512x512x10全一矩阵执行所有元素加1操作,分别用python和C++来执行,看需要的时间。
具体的代码:

#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)

运行结果(睁大眼睛看清楚哟):

python调用c 程序 python调用c++_python_05