- Boost::Python 入坑随笔 (一): 编译安装及 Hello World ! (。・∀・)ノ
- 前言
- 环境
- 编译 Boost 库
- 创建 user-config.jam 文件
- 编译
- b2 / bjam 部分命令参数说明
- 使用及测试
- 创建项目并配置 Boost::Python
- 测试 Hello Boost Python
- 引用及参考
前言
Boost::Python
优美胜于丑陋 ( Python 以编写优美的代码为目标 ) 明了胜于晦涩 ( 优美的代码应当是明了的,命名规范,风格相似 ) 简洁胜于复杂 ( 优美的代码应当是简洁的,不要有复杂的内部实现 ) 复杂胜于凌乱 ( 如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁 ) ...
而 Boost::Python 就是一个高度封装好的 Python / C API,它能简化 C++ 代码,使得为 Python 编写 C++ 扩展更为简单方便。甚至还能以 OOP 风格在 C++ 中编写 Python 对象的操作。Pythonic 即为正义 ╰( ̄ ω  ̄o)。因此,我也开始了我的 Boost::Python 入坑之旅。
环境
先说说我的环境配置:
- Windows 10 64 bit
- Anaconda Python 3.7.2 ( 64 bit )
- Visual Studio 2017 ( msvc v14.16 )
- Boost 1.69
注 : VS 2017 和 Boost 1.69
编译 Boost 库
编译应该是我踩坑过程当中遇到的最为繁杂的一步了,好在现在已经轻车熟路。不要慌,一步一步来。实际上 Boost 较早一些的版本是提供了 Windows 预编译二进制包的,比如 Boost 1.67
。但是它里边编译好的是 Python 2.7 的,所以想要自己对应 Python 版本的 Boost::Python,还是得自己编译 ( ̄ ▽  ̄)"
创建 user-config.jam
文件
解压之前下载好了的 boost_1_69_0.zip
( or boost_1_69_0.7z
) 文件。打开解压好的 boost_1_69_0
文件夹,在该文件夹下新建一个 user-config.txt
文件,并在里边加上几句:
using msvc : 14.1;
# 路径仅供参考
using python : 3.7
: "C:Usersuser nameAnaconda3python.exe"
: "C:Usersuser nameAnaconda3include"
: "C:Usersuser nameAnaconda3libs" ;
其中 using msvc : 14.1
指定编译器为 msvc 14.1
即 VS 2017,如果是 VS 2015 的话应填 using msvc : 14.0
。 using python
则是指定 Python 版本及其路径,因为我用的是 Anaconda Python 3.7.2,所以第一处填 3.7,第二处则是 Anaconda 根目录下的 python.exe
的目录。第三四处也都在 Anaconda 根目录下,注意顺序和符号填进去就行了。切记版本号和路径填你自己的,别只复制粘贴。保存 user-config.txt
文件后并将其后缀修改为 .jam
,即 user-config.jam
。
编译
Boost 库提供了强大的编译工具 b2.exe
和 bjam.exe
,其中 b2.exe
为新版本的编译工具,我们使用它来编译 Boost::Python 64 位静态库。在 boost_1_69_0
文件夹下打开命令行 ( Powershell 等),输入以下命令回车即可。
.b2 --with-python --prefix="g:boost" install toolset=msvc-14.1 link=static address-model=64
该指令会同时编译 Release
和 Dubug
版本,若要单独编译某一个版本,则可使用以下指令:
- Release 版
.b2 --with-python --prefix="g:boost" install toolset=msvc-14.1 variant=release link=static address-model=64
- Dubug 版
.b2 --with-python --prefix="g:boost" install toolset=msvc-14.1 variant=debug link=static address-model=64
注:由于还要复制各种头文件,所以总耗时大概 10 ~ 20 min。
b2 / bjam 部分命令参数说明
-
--with-
|--without-
--with-
后面接要编译的 Boost 的库名,如--with-python
即仅编译 Boost::Python 库。相对的,--without-python
即为编译除 Boost::Python 之外全部库。如果要编译 ( 或不编译 ) 多个库的话,可用多条with | without
语句来指定,缺省则为全部编译。 -
install
|stage
stage
即只生成库,而install
还会生成include
目录。通过--prefix="g:boost"
指定install
生成好的库的路径为"g:boost"
。如果是stage
则由--stagedir=
来指定。 -
toolset
指定编译工具,此处我们指定为msvc 14.1
,即 VS 2017 的编译器 -
link
即指定编译为动态库还是静态库 (.dll | .lib
),shared
即编译为动态库,static
即为静态库,不填则默认编译为静态库。一般而言静态库体积要大一些,但不用带 Boost::Python 的 DLL 文件,部署和使用也较为方便; 动态库的话相对体积较小(也小不了多少),但必须用带 Boost::Python 的 DLL 文件。选择静态库还是动态库这个得自己取舍。 ( 小孩子才做选择,我全都要( •̀ ω •́ )✧ ) -
address-model
指定编译为 32 位还是 64 位,我们指定address-model=64
即编译为 64 位。
使用及测试
编译好后怎么能少的了来一个 Hello World!
呢?常言道:" 没有经过 Hello World!
洗礼的代码是没有灵魂的!"。
走起 ヾ(•ω•`)o
创建项目并配置 Boost::Python
打开 VS 2017 并创建一个 C++ 空项目 HelloBoostPython
将工具栏那的改为 Release x64
接下来打开项目属性,即解决方案管理器中选择该项目 右键->属性
在 配置属性->常规 中修改目标文件名( Hello_Boost
)及其扩展名( .pyd
),配置类型改为 动态库(.dll)
然后转到 配置属性->VC++目录
- 包含目录中加上 Anaconda 安装目录中的
include
目录,以及之前编译时--prefix="g:boost"
指定的那个目录下的includeboost-1_69
,如下所示:
C:Usersuser nameAnaconda3include
G:boostincludeboost-1_69
- 库目录同理,加上 Anaconda 安装目录中的
libs
目录以及--prefix="g:boost"
指定目录下的lib
,如下:
C:Usersuser nameAnaconda3libs
G:boostlib
注 : 这步完成后,切记别忘了点 确定
。
测试 Hello Boost Python
向项目中添加一个 main.cpp
文件,并加入以下代码:
// File : main.cpp
// 不在 #include <boost/python/...> 之前加上下面的宏定义的话
// 编译器会默认使用 Boost::Python 的动态链接库
#define BOOST_PYTHON_STATIC_LIB
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
const char * hello_boost() {
return "Hello Boost::Python!";
}
const char * hello_world() {
return "Hello World!";
}
// 此处 Hello_Boost 应该与之前设置的目标文件扩展名一致
// 否则想知道后果的话请自行尝试 ╮(╯▽╰)╭
BOOST_PYTHON_MODULE( Hello_Boost ) {
using namespace boost::python;
def( "hello_boost", hello_boost );
def( "hello_world", hello_world );
}
接下来按 Ctrl + F7
编译,可能会遇到一个神奇的错误
error C3861: 'unwind_type': identifier not found
如果用的是最新版的 VS 2017 的话,肯定会碰上这个问题,这个问题似乎只会发生在 msvc 14.16
及以上的版本中。不要慌,问题不大,因为我在 Github 中找到了解决方法。( •̀ ω •́ )y
includeboostpythondetailunwind_type.hpp
找到上边这个文件,将里边所有的
#ifndef _MSC_VER
改为
#if (!defined(_MSC_VER) || _MSC_VER >= 1915)
具体可参考 Here
这样编译应该就没问题了,编译后会生成一个 Hello_Boost.pyd
文件,即 Python 的动态链接库文件。可能还会遇到下面这个错误,忽略即可( ̄︶ ̄)↗
在 Hello_Boost.pyd
该文件路径下打开 Powershell,进入 Python 交互式命令窗口,import
那个 .pyd
文件 (不用加后缀),我们来测试一波~
如果你也看到如上结果,那恭喜你成功啦 o( ̄ ▽  ̄)o
引用及参考
Code Style — The Hitchhiker's Guide to Pythondocs.python-guide.org
PEP 20 -- The Zen of Pythonwww.python.org