python调用C++之pybind11入门(相互调用)
python调用C/C++有不少的方法,如boost.python, swig, ctypes, pybind11等,这些方法有繁有简,而pybind11的优点是对C++ 11支持很好,API比较简单,现在我们就简单记下Pybind11的入门操作。
1. pybind11简介与环境安装
pybind11是一个轻量级的只包含头文件的库,它主要是用来在已有的 C++代码的基础上做扩展,它的语法和目标非常像Boost.Python,但Boost.Python为了兼容现有的基本所有的C++编译器而变得非常复杂和庞大,而因此付出的代价是很多晦涩的模板技巧以及很多不必要的对旧版编译器的支持。Pybind11摒弃了这些支持,它只支持python2.7以上以及C++ 11以上的编译器,使得它比Boost.Python更加简洁高效。
为了使用pybind11,我们需要支持C++ 11标准的编译器(GCC 4.8以上,VS 2015 Update 3以上)以及python 2.7以上的版本,还需要下载CMake,有了这些以后,
1. 首先,我们从 pybind11 github网址:https://github.com/pybind/pybind11 上下载源码。
2. cmake工程之前,要先安装pytest pip install pytest,否则会出错
3. 用CMake编译并运行测试用例:
mkdir build
cd build
cmake ..
cmake --build . --config Release --target check
1
2
3
4
如果所有测试用例都通过了,说明安装成功了。
2. python调用C++
下载编译好pybind11之后,我们就可以开始对着官方的pybind11 Tutorial进行学习了,详细的入门教程及语法请参考官方文档,这里,我们简单演示下如何编写供python调用的C++模块.
首先,我们编写一个C++源文件,命名为example.cpp
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int i, int j)
{
return i + j;
}
PYBIND11_MODULE(example, m)
{
// optional module docstring
m.doc() = "pybind11 example plugin";
// expose add function, and add keyword arguments and default arguments
m.def("add", &add, "A function which adds two numbers", py::arg("i")=1, py::arg("j")=2);
// exporting variables
m.attr("the_answer") = 42;
py::object world = py::cast("World");
m.attr("what") = world;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2.1 编译
然后,在windows下使用工具vs2015 x86 Native Tools Command Prompt (因为我的python是32位版本,如果是64位版本的,请使用vs2015 x64 Native Tools Command Prompt)进行编译:
cl example.cpp /I "H:/Allfiles/pybind11/include" /I "C:/Python27/include" /LD /Fe:example.pyd /link/LIBPATH:"C:/python27/libs/"
编译成功后,会在example.cpp相同目录下生成example.pyd文件,这个就是python可以直接导入的库,运行:
import example
example.add(3, 4)
[out]: 7
1
2
3
4
有了编译成功的模块,便可以使用我在另一篇博客Python模块搜索路径中提到的方法,将其用.pth或者PYTHONPATH的方法加入到python搜索路径,以后在我们自己的环境中就可以随时随地使用这个模块啦。
2.2 CMake的编译方法
当然,我们也可以使用CMake进行编译。首先写一个CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
project(example)
add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)
1
2
3
4
5
这里要求example.cpp放在和pybind11同一级的目录下,然后CMake,便会生成一个vs 2015的工程文件,用vs打开工程文件进行build,就可以生成example.pyd了。
3. C++调用python
使用pybind11,也很容易从C++里调用python脚本:
首先,我们用vs 2015新建一个工程,并且将Python的包含目录和库目录,以及pybind11的包含目录配置到工程,我的配置如下:
然后,新建一个源文件example.cpp:
#include <pybind11/embed.h>
#include <iostream>
namespace py = pybind11;
int main() {
py::scoped_interpreter python;
//py::module sys = py::module::import("sys");
//py::print(sys.attr("path"));
py::module t = py::module::import("example");
t.attr("add")(1, 2);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
最后,在工程目录下加入脚本example.py:
def add(i, j):
print("hello, pybind11")
return i+j
1
2
3
运行工程,得到如下的结果:
运行成功!!!
总结
本文中我们简单介绍了怎么使用pybind11进行python和C++的相互调用,这些只是入门级别的例子,但是可以work了,这很重要。深入进行研究使用,还是等以后用到再说吧。
参考文献
pybind11 github
pybind11 Tutorial
C++与Python的互操作
Building and testing a hybrid Python/C++ package
---------------------
作者:fitzzhang
来源:CSDN
原文:https://blog.csdn.net/fitzzhang/article/details/78988682
版权声明:本文为博主原创文章,转载请附上博文链接!
python调用C++之pybind11入门(相互调用)的更多相关文章
- JAVA与.NET的相互调用——通过Web服务实现相互调用
JAVA与.NET是现今世界竞争激烈的两大开发媒体,两者语言有很多相似的地方.而在很多大型的开发项目里面,往往需要使用两种语言进行集成开发.而很多的开发人员都会偏向于其中一种语言,在使用集成开发的时候 ...
- python和shell之间变量的相互调用
python -> shell: 1.环境变量 2.字符串连接 3.通过管道 import os var=’123’ os.popen(’wc -c’, ’w’).write(var) 4.通过 ...
- 各编程语言 + aardio 相互调用示例
代码简单.复制可用.aardio 快速调用 C,C++,C#,Java,R,V,Python,JavaScript,Node.js,Rust,PHP,Ruby,PowerShell,Fortran,D ...
- JAVA与.NET的相互调用——利用JNBridge桥接模式实现远程通讯
分布式开发的历史 利用Remote方式调用远程对象实现服务器与客户端之间通讯是一种常用的网络开发方式,在.NET与JAVA开发当中,对Remote远程对象早已有着足够的支持(对Remote远程对象调用 ...
- Python实例浅谈之三Python与C/C++相互调用
一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不经过 ...
- python - 函数的相互调用 及 变量的作用域
# -*- coding:utf-8 -*- '''@project: jiaxy@author: Jimmy@file: study_函数的相互调用及变量的作用域.py@ide: PyCharm C ...
- Python与C/C++相互调用(python2 调c++那个试了ok)
一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不经过 ...
- Python与C/C++相互调用(转)
原文链接 作者 一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库 ...
- c/c++再学习:C与Python相互调用
c/c++再学习:Python调用C函数 Python 调用C函数比较简单 这里两个例子,一个是直接调用参数,另一个是调用结构体 C代码 typedef struct { int i1; int i2 ...
随机推荐
- (转载)UTF-8和GBK的编码方式的部分知识:重要
GBK的文字编码是双字节来表示的,即不论中.英文字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1. 至于UTF-8编码则是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节) ...
- ajax等待(比较慢时)(显示图片)
html页面 <div style="display:none;" id="loading-mask"></div> <div i ...
- CMD命令进入文件夹
cmd 进入E文件夹 E: 查看文件夹目录 dir 进入某个文件夹 cd 目录
- php 在windows下配置虚拟目录的方法
1.先找到apache的配置文件 httpd.conf 找如如下代码: # Virtual hosts#Include conf/extra/httpd-vhosts.conf 把# Include ...
- linux系统中,查看当前系统中,都在监听哪些端口
需求描述: 查看当前系统中都监听着哪些的端口,用netstat命令,在此记录下 操作过程: 1.查看系统中都在监听哪些端口 [root@testvm home]# netstat -ntl Activ ...
- ArcGIS Server密码丢失
http://jingyan.baidu.com/article/1e5468f90f6465484961b70d.html 1.cd D:\Program Files\ArcGIS\Server\t ...
- python2.0_day18_django_ORM
Django_ORMday15\16我们学到的ORM都是最基本的增删改查.下面我们稍作升级,学习下高级点的增删改查.先创建一个新的APP项目 python3. manage.py startapp b ...
- capitalize()
capitalize() 是字符串的一个方法,用于把字符串的第一个字母转换成大写 In [1]: str = 'hello world' In [2]: str.capitalize() Out[2] ...
- 第十六篇:初探IO复用
前言 在之前的文章中,我具体实现了一个并发回射服务器并给它加载了僵尸子进程的自动清理信号机制.在正常情况下,它已经可以很好地工作了,但它能否合理应对一些特殊情况呢? 问题发现 先来看看当服务器的客户子 ...
- linux文件类型详解
*nix 有各种的文件类型 当#ls -la后,会发现在权限位前有个 - 有些是 b 有些是 d 这个位置就是文件类型的标示 普通文件regular file, 用 - (破折号)标示, 比如 ...