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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏黑白安全

Linux 系统的 beep 包中存在竞争条件漏洞,可被黑客利用探测机密文件

Linux 发行系统 Debian 和 Ubuntu 中预装的 beep 包存在竞争条件漏洞,黑客可利用这个漏洞探测到计算机中的文件(包括 root 用户的机密...

8020
来自专栏大魏分享(微信公众号:david-share)

VMware软件定义数据中心分析工具介绍----第三终结篇

在本文连载的第一篇中,我向大家介绍了vROps的基本架构、vROps的指标含义,以及如何自定义告警。第二篇中,介绍了如何自定义仪表盘。在本篇中,我将介绍如何自定...

40580
来自专栏性能与架构

linux性能监控工具nmon

nmon是什么 nmon 是linux的一个性能数据收集分析工具,简单易用 可以方便的收集CPU、内存、硬盘、网络等状态数据,平时查看这些数据需要使用不同...

390110
来自专栏hotqin888的专栏

onlyoffice document server实时文档协作的部署与开发细节

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/det...

15910
来自专栏性能与架构

服务网关 Service Gateway

微服务架构把网站从一个单体结构拆分为多个独立服务的集合 单体结构,各个模块都在一起 ? 微服务结构,各服务模块独立部署 ? 带来了很多好处,例如,提高了系...

42350
来自专栏月色的自留地

mac电脑进行可见光通信实验要点

12460
来自专栏蛋未明的专栏

PHP压测优化

28230
来自专栏游戏杂谈

nginx的反向代理缓存

假设有两台物理机,他们分属于不同的域名,以webgame的游戏运营商和开发商为例,运营商需要获取游戏中的排行数据,开发商为了过多对游戏服务器的请求,会在发起请求...

51420
来自专栏快乐八哥

Angular企业级开发(1)-AngularJS简介

AngularJS介绍 AngularJS是一个功能完善的JavaScript前端框架,同时是基于MVC(Model-View-Controller理念的框架,...

24280
来自专栏杨建荣的学习笔记

MySQL备份调度自动化实现思路

昨天整理了下备份调度的思路 批量任务的并发调度和时间调度,整体来说已经自己已经思路很清晰了,所以今天就开始实现整个过程。

12920

扫码关注云+社区

领取腾讯云代金券