python 调用 C/C++

来源:互联网 发布:linux常用命令 cat 编辑:程序博客网 时间:2024/06/15 15:20

1.问题描述

python相比C/C++,具有很多封装好的高级的API,极大地方便了平时的程序开发。但是有的时候我们需要的某个功能模块python里面并没有实现,但是C/C++下有现有的程序,那么一种方法就是用python调用C/C++的模块.下面举的例子为:
假设我需要计算任意两个四边形的交叠率(intersection over union),这个可以利用C++下的boost库很方便的实现,现在我需要在python环境下调用这个写好的C++函数

2.问题解决

2.1 将C++程序编译成动态链接库

假设当前目录下存在文件compute_iou.h以及compute_iou.cpp, 其中compute_iou.h如下所示:

#include <vector>#include <boost/geometry/geometry.hpp>#include <boost/geometry/geometries/register/point.hpp>#include <boost/geometry/geometries/register/ring.hpp>typedef struct{    float x,y;}MyPoint;typedef boost::geometry::model::polygon<MyPoint> Polygon;BOOST_GEOMETRY_REGISTER_POINT_2D(MyPoint, float, boost::geometry::cs::cartesian, x, y)BOOST_GEOMETRY_REGISTER_RING(Polygon::ring_type)extern "C" float compute_box_iou(float x11,float x12,float x13,float x14,float y11,float y12,float y13,float y14,float x21,float x22,float x23,float x24,float y21,float y22,float y23,float y24,float r1,float r2,float c1,float c2);  

需要注意的是,因为python实质上只能调用C的函数,所以我们要在C++函数前面加上extern C的标志
终端执行编译命令,生成.so文件

g++ -std=c++11 -o libcompute_iou.so -shared -fPIC compute_iou.cpp -L boost

2.2 python中调用动态链接库

python中使用模块ctypes来调用C的动态链接库,如下所示:

from __future__ import absolute_importfrom __future__ import divisionfrom __future__ import print_functionfrom ctypes import *# load动态链接库so = cdll.LoadLibrary('libcompute_iou.so')py_iou = so.compute_box_iou# 设置函数返回值的类型py_iou.restype = c_float# 设置传入函数的参数的类型x11 = x12 = c_float(10)x13 = x14 = c_float(20)y11 = y14 = c_float(10)y12 = y13 = c_float(20)x21 = x22 = c_float(10)x23 = x24 = c_float(20)y21 = y24 = c_float(10)y22 = y23 = c_float(20)r1 = r2 = c1 = c2 = c_float(10)# 调用函数计算iouiou = py_iou(x11, x12, x13, x14, y11, y12, y13, y14, x21, x22, x23, x24, y21, y22, y23, y24, r1, r2, c1, c2)print('iou = {}'.format(iou))# 程序运行结果,两个相同的四边形,iou=1.0,结果正确>>>iou = 1.0

需要注意的是,我们在用ctypes调用动态链接库的时候,需要设置传入参数以及返回参数的类型,使其符合ctypes的类型要求,比如说,如果我们需要传递一个float类型的参数到函数,我们需要在python中设置变量的类型为ctypes.c_float,函数返回值的类型可以用restype来设置,这里我们希望返回的iou是float类型。ctype-C-python之间的类型对应表如下所示:
ctypes