boost.python 庫提供了便捷的方法來將 C++ 中的函數、類等導入到 Python 中使用,咱們只須要添加少許代碼,就能 C++ 與 Python 的整合。javascript
將 C++ 代碼藉助 boost.python 編譯成 Python 模塊以後,咱們能夠像導入標準模塊那樣,將該模塊導入,在 Python 中使用 C++ 中的類來建立變量,並調用其方法。總之,咱們能夠很方便地在 Python 中調用 C++ 實現的功能,二者的結合,既提升了程序的運行效率,也提升了編程的效率。html
boost.python 庫的安裝和使用的具體步驟以下。java
開發環境:Windows 十、Visual Studio 2015
版本:boost.python 1.64.0
下載地址:www.boost.org/users/histo…python
一、將下載下來的 boost.python 壓縮包解壓到 D 盤,獲得 D:\boost_1_64_0c++
二、運行目錄下的 bootstrap.bat 批處理文件,等待一下子。
建立配置文件,用於靜態庫的編譯,內容以下:編程
# Configure specific Python version.
using python : 2.7
: C:/Python27/python.exe
: C:/Python27/include #directory that contains pyconfig.h
: C:/Python27/libs #directory that contains python27.lib
: <toolset>msvc ;複製代碼
這裏用的是 Python2.7 版本,你須要將其中的 C:/Python27
改成你電腦中 Python 的安裝路徑,msvc
表示使用 Visual Studio 的工具箱。bootstrap
三、打開命令行,經過 cd 命令將工做目錄切換到 D:\boost_1_64_0 目錄下,而後執行命令:數據結構
b2 toolset=msvc-14.0 --with-python variant=debug runtime-debugging=on link=static --user-config=user-config.jam stage複製代碼
該命令會根據上面的配置文件,生成須要用到的靜態庫文件。函數
在 Visual Studio 中打開 工程屬性 -> 配置屬性 -> C/C++工具
在右側的「附加包含目錄」中添加 D:\boost_1_64_0;C:\Python27\include
,這兩個目錄存放了須要的頭文件。
打開 工程屬性 -> 配置屬性 -> 連接器 -> 常規
在右側的「附加庫目錄」中添加 C:\Python27\libs;D:\boost_1_64_0\stage\lib
,這兩個目錄存放連接階段須要用到的庫文件。
編譯完 boost.python 庫,並設置好VS工程項目以後,就能夠對 C++ 代碼進行封裝了。
首先,咱們須要在 C++ 代碼添加一個宏定義,用於告訴 VS 咱們要使用的是已經編譯好的 boost.python 靜態連接庫,該宏定義須要放在全部代碼以前(包括 #include 語句)。
#define BOOST_PYTHON_STATIC_LIB複製代碼
例若有這麼一個 C++ 函數:
char const* greet() {
return "hello, world";
}複製代碼
咱們須要添加以下代碼:
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello_ext)
{
def("greet", greet);
}複製代碼
注意,代碼中的 hello_ext 是目標 Python 模塊的名稱,模塊名需與文件名相對應。
該代碼能夠單獨放在一個源文件中,經過 #include 來關聯,也能夠直接添加到已有的源代碼中。若是源代碼已經編譯成 .lib 文件,這種狀況下就能夠在單獨的源文件中寫接口。
打開 工程屬性 -> 配置屬性 -> 常規,在右側的 項目默認值 -> 配置類型 中選擇「動態庫(.dll)」,這將使 VS 生成 dll 動態庫文件,而非 exe 可執行文件。
選擇 生成 -> 生成解決方案,生成 .dll 文件,將該文件複製到 Python 項目目錄下,將後綴改成 .pyd,獲得 hello_ext.pyd 文件,該文件即爲 Python 的庫文件,可直接經過 import 導入。
咱們能夠像調用標準 Python 庫那樣調用咱們本身生成的模塊:
>>> import hello_ext
>>> print hello_ext.greet()
hello, world複製代碼
上面所給的例子是函數包裝器的示例,若是要導出的是 C++ 中的類,則須要使用類包裝器來封裝接口。
例如咱們要導出以下的 C++ 類給 Python 使用:
class World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};複製代碼
咱們須要在原有代碼中添加如下包裝器,從而將接口提供給 Python:
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}複製代碼
而後按照上述的步驟生成 .pyd 模塊文件,在 Python 中調用:
>>> import hello
>>> planet = hello.World()
>>> planet.set('howdy')
>>> planet.greet()
'howdy'複製代碼
boost.python 庫仍是很是方便的,正常狀況下,咱們無需改變原有的代碼就能將數據結構和函數導出到 Python 中。比起本身使用 python.h 庫來實現 C++ 與 Python 的整合,不只僅是通常的高效。最讓我感到驚喜的是,boost.python 庫還提供了諸如 boost::python::list 的數據類型,咱們能夠直接在 C++ 中像在 Python 中使用列表那樣,將不一樣的數據類型添加到一個 list 中。咱們也能夠藉助 list 類型,方便地將多個數據以列表的形式傳遞給 Python。
上面的步驟中,最容易出現問題的是「生成 dll 文件」這一步,可能會有庫文件找不到的狀況,或者符號加載失敗等狀況。若是遇到這些問題,請檢查是否正確編譯了 boost.python 庫、是否在工程屬性中的添加了正確的頭文件路徑和附加庫路徑、安裝的 python 版本的位數與VS配置的位數是否一致等等。若是實在解決不了,能夠經過 Google 來搜索解決方案,StackOverflow 上有許多關於這些問題的解決辦法,也歡迎給我留言,針對遇到的問題進行交流討論。
更多關於 boost.python 的使用說明,能夠參考:Boost.Python Tutorial - 1.64.0