提出问题
最近因为项目原因,需要测试一批C++代码,并且还有个需求,要求把c++代码封装成python可以直接调用的库。虽然之前听说过可以这样做,而且python底层也是c++写的,所以之前只用,而没思考过这个问题,因此,此次做了一个尝试。
解决问题
其实该问题的解决主要依赖一个名为pybind11的接口。下面详细介绍一下封装过程。
-
首先通过链接下载pybind11,最好与C++工程放在同一级目录,且无需像其他第三方库源码一样编译,直接放入目录中即可。
-
在C++源码工程中配置相关第三方库的配置(这里我主要导入了相关第三方库,例如:gdal、opencv等,这些库用之前需要进行CMake编译),如无第三方库,则更简单,直接配置pybind11即可。具体配置如下:
可以看到导入的第三方库有个细节,全是以相对路径调用,这里主要是为了工程迁移方便。当然,这里不是强调这个问题,需要强调的是pybind11的配置。pybind11的配置需要Anaconda的支持,因为我们后续是在Anaconda的虚拟环境中进行的,因此我们需要配置该设置。具体如上所示。
-
其他配置,这个极其重要。“常规”选项中配置类型一定要选择“动态库(.dll)”,“高级”选项中“目标文件扩展名”一定要改为“.pyd”,这样才能满足python库的调用。
-
完成以上的设置,才是基础,没到重点。重点是怎么写代码绑定C++块。
- 首先,是在头文件的调用,如下:
#include <pybind11/pybind11.h> namespace py = pybind11;
- 其次,是绑定代码的撰写,如下:
PYBIND11_MODULE(SuperPixel, m) { // optional module docstring m.doc() = "pybind11 SuperPixel plugin"; // expose add function, and add keyword arguments and default arguments m.def("SuperPixel", &SuperPixel, "A function to make superpixel"); }
其实,也蛮简单的,主要记住一点是封装函数导出函数的名字以及要封装的函数的名字最好保持一直,要不然可能报错。
完成以上步骤,就可以生成解决方案了,直接在Visual Studio里编译即可。编译后,会在x64的Release文件夹里多出几个文件夹,如下图所示。这里有个极其重要的点,我就是因为这个点,折腾了一天。注意:绿色框是运行生成的文件,我们需要选取“SuperPixel.pyd”这个文件,而同样重要的是,第三方库(红色框的动态库)极其重要,我们要一同复制,因为“SuperPixel.pyd”的运行依赖这些库,要不然一直报错:ImportError: DLL load failed while importing SuperPixel: 找不到指定的模块。
以上选取的四个模块,我们要复制到Anaconda虚拟环境中的“DLLs”文件下,以供python调用。
- 首先,是在头文件的调用,如下:
-
通过以上五个步骤的完成,我们才能最终生成python能调用的第三方库。如图所示,生成了超像素图像。
from SuperPixel import SuperPixel num = 1 input_dir = "./hyper" output_dir = "./hyper/h_csv" vis_dir = "./hyper/h_contour" prefix = "CCS_h" superpixels = 3000 ishyper=True SuperPixel(num, input_dir, output_dir, vis_dir, prefix, superpixels, ishyper) print('done')
文章评论