Python调用C/C++的方法——3(Boost.Python)

之前关于Python调用C/C++介绍了:
1.ctypes方式加载并调用C/C++ 动态链接库的方式;
2.使用C/C++编写Python扩展模块的方式。
今天的笔记记录的是使用Boost.Python的方式。

Boost.Python介绍:
Boost.Python是一个开源C++库,它提供了一个简明的IDL式的接口用于绑定C++类和函数到Python。 得益于C++编译期的内部处理(译注:原文是introspection)和最近开发的元编程(metaprogramming)技术,成就了Boost.Python不需引入一种新的语法而只用纯C++的实现。Boost.Python丰富的特性集合以及它的高阶接口使得工程师像混合系统(译注:hybrid system)那样做打包的事情成为可能,并且程序员让在应用C++高效的编译期多态性以及Python非常方便的运行期多态性的时候获得易用性和一致性;
Boost库是非常强大的库, 其中的python库可以用来封装c++被python调用, 功能比较强大, 不但可以封装函数还能封装类, 类成员。

文档:
https://www.boost.org/doc/libs/1_65_1/libs/python/doc/html/index.html

前提
使用boost python库需要先进行安装,可能有些版本的操作系统内是有集成的。(例如我使用的Ubuntu16.04)
安装: sudo apt install libboost-python-dev

简单的例子
hello.cpp

#include <boost/python.hpp>
char const* greet()
{
   return "hello, world";
}

int add(int x,int y)
{
    return x+y;
}

BOOST_PYTHON_MODULE(hello)     // 参数hello为模块的名字,没有引号
{
    using namespace boost::python;
    def("greet", greet);    // "greet"是python调的方法名,greet是C++的方法
    def("add",add);
}

编译:

g++ -c -fPIC -o hello.o hello.cpp -I /usr/include/python2.7/
g++ -shared -Wl,-soname,hello.so -o hello.so  hello.o -L/usr/lib/x86_64-linux-gnu -lpython2.7 -lboost_python
或:
g++ -shared -o hello.so -fPIC hello.cpp -I/usr/include/python2.7/ -lpython2.7 -lboost_python
注意:源代码hello.cpp的位置一定要在声明头文件和链接库的左面(g++自右向左解析)。以下是我趟过的坑:
/*
g++ -fPIC -o hello.so -shared -I/usr/include/python2.7/ -L/usr/lib/x86_64-linux-gnu -lboost_python hello.cpp
编译正常通过,且生成hello.so但是ldd发现没有链接libboost_python这个库的任何信息,import 报错:
'''
ImportError: ./hello.so: undefined symbol: _ZNK5boost6python7objects21py_function_impl_base9max_arityEv 
'''
此问题既由于g++语句顺序不当引起,由于gcc/g++语句都由右向左解析,所以如果把源代码放在链接库的右面则有可能链接失败。
另:
    如果boost_python库的路径不在ld默认的库中,可以通过-L添加,例如我的libboost_python.so位置在/usr/lib/x86_64-linux-gnu/下:可以通过:-L/usr/lib/x86_64-linux-gnu指定,或添加到/etc/ld.so.conf.d/中并执行ldconfig
*/

脚本编译方式:python setup.py build
setup.py

## python 提供了setup、Extension方法实现编译和模块创建。
#!/usr/bin/env python
from distutils.core import setup
from distutils.extension import Extension

setup(name="hello.test.python",
 ext_modules=[
  Extension("hello", ["hello.cpp"],    ## hello是模块名,hello.cpp是源代码文件
  libraries = ["boost_python"])    ## 链接的库
 ])

测试代码:test.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
## 自定义的C++编写的模块
import hello
if __name__ == "__main__":
  ## 简单的两个测试
  print hello.greet()
  print hello.add(1,2)
  '''
  hello, world
  3
  '''
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值