Python和C++的混合编程(使用Boost编写Python的扩展包)
想要享受更轻松愉悦的编程,脚本语言是首选。想要更敏捷高效,c++则高山仰止。所以我一直试图在各种通用或者专用的脚本语言中将c++的优势融入其中。原来贡献过一篇《c++和js的混合编程》也是同样的目的。
得益于机器学习领域的发展,Python最近一直维持热度,但Python的速度,比node.js都差距不小,所以使用c++来提高一些速度更有必要。
编写Python的扩展模块已经有不少的不错的框架,但感觉上boost是最好用的一个。
环境准备
本文的实验环境为mac电脑。使用Linux环境通常也可以使用apt或者yum来安装配置对应的开发环境,请查看其它介绍文档。
在mac上准备环境很容易,首先要已经安装Xcode,并且安装了Xcode的命令行工具。其次要安装Homebrew扩展包管理工具。这部分是基础的开发环境,这里不做额外说明。
在命令行执行
brew install boost-python3,一行命令就可以安装完成Python模块的开发环境。(本例中完全使用Python3为例来说明,如果想制作Python2的扩展包,请根据需要修改相应的名称和版本号)。
简单示例
从boost官网抄了一个简单的示例,包括了初始化、从Python传递参数给c++和从c++返回结果给Python的一个基本流程。源代码非常短,请看下面:
#include <string> #include <boost/python.hpp> using namespace std; using namespace boost::python; struct World{ void set(string msg) { this->msg = msg; } string greet() { return msg; } string msg; }; //特别注意下面的模块名hello同将来引入Python的模块名、编译完成的文件名,三者必须相同 BOOST_PYTHON_MODULE(hello){ class_<World>("World") .def("greet", &World::greet) .def("set", &World::set) ; }
编译
假设上面的c++代码保存为hello.cpp文件。使用如下两行命令可以完成编译:
#生成.o临时编译文件 g++ -fpic -c hello.cpp $(pkg-config --cflags python3) #生成.so工作文件 g++ -shared -o hello.so hello.o -lboost_python37 $(pkg-config --cflags --libs python3)
上面的两行编译命令中,有两个编译参数可能是需要根据具体版本做调整的,一个是pkg-config库管理工具中的python3,这个名称和版本号可以检查如下路径的配置文件,根据自己需要选择对应的库版本,比如python3对应需要有python3.pc文件:
ls /usr/local/lib/pkgconfig/python*pc
另外一个是第二行命令中的-lboost_python37,这个检查已经安装的库版本来决定,比如-lboost_python37对应需要有libboost_python37.dylib文件,特别注意这个版本同将来运行的python环境版本必须精确一致,小版本也必须相同:
ls /usr/local/lib/libboost_python*
验证
编译完成会在当前目录生成hello.so文件,这时候可以直接使用Python的交互模式来验证扩展模块的使用:
$ python3 Python 3.7.0 (default, Sep 18 2018, 18:47:22) [Clang 9.1.0 (clang-902.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import hello >>> test=hello.World() >>> test.set("hello 世界"); >>> test.greet() 'hello 世界'
bjam编译
boost官方推荐使用Boost.Build系统bjam来编译,比Makefile之类的确会略微的方便一点,这里介绍出来供参考。
安装bjam:
brew install bjam。
在当前目录建立一个文本文件Jamroot,内容为:
import python ; using python : 3 ; lib boost_python37 ; project demo : requirements <location>. <library>boost_python37 ; #注意下面的hello,同cpp文件中最后导出的模块名必须相同 python-extension hello : hello.cpp : <cxxflags>"`pkg-config --cflags python3`" : <linkflags>"`pkg-config --libs python3`" ;
在命令行执行bjam命令,会自动编译生成hello.o及hello.dylib文件,.o文件为临时文件可以删除,.dylib文件改名为.so文件就是我们需要的Python扩展库,使用起来是完全相同的。
参考资料
https://www.boost.org/doc/libs/1_60_0/libs/python/doc/html/tutorial/index.html
- 使用C/C++编写Python扩展库
- 利用C++ Boost编写扩展Python模块
- 利用C++ Boost编写扩展Python模块
- 扩展Python__在python脚本中使用其他语言(c/c++/java/c#)编写的模块
- 使用Python WSGI编写Web服务器前端,并利用Boost.Python在同一进程内连接到C++服务后端实现
- 利用C++ Boost编写扩展Python模块
- c++ python交互之boost.python 简集之Vector(map)混合使用
- C++使用boost python import 其他路径的模块
- 用C/C++编写Python扩展
- 【Programming In Lua (2E) 笔记】5:使用C++为Lua编写扩展库(macOS上两种动态库格式的坑)
- C++ 编写Python扩展(密码生成器)
- 使用C++扩展Python的功能
- 使用SWIG实现C++扩展Python
- 使用C++扩展Python的功能 转自:http://blog.csdn.net/magictong/article/details/8897568#comments
- 使用 c++ 扩展python
- 用boost.python为python写c/c++扩展曲折配置最终成功历程
- (转)使用C/C++扩展Python
- 使用swig实现C++的python扩展功能
- Python性能提升一 —— 高计算模块使用C++编写
- 手动使用C/C++编写Lua扩展插件