利用boost.python庫實現C++與Python的整合

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

1、編譯 boost.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複製代碼

該命令會根據上面的配置文件,生成須要用到的靜態庫文件。函數

2、VS 工程配置

在 Visual Studio 中打開 工程屬性 -> 配置屬性 -> C/C++工具

在右側的「附加包含目錄」中添加 D:\boost_1_64_0;C:\Python27\include,這兩個目錄存放了須要的頭文件。

打開 工程屬性 -> 配置屬性 -> 連接器 -> 常規

在右側的「附加庫目錄」中添加 C:\Python27\libs;D:\boost_1_64_0\stage\lib,這兩個目錄存放連接階段須要用到的庫文件。

3、添加 C++ 代碼

編譯完 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 文件,這種狀況下就能夠在單獨的源文件中寫接口。

4、生成 dll 文件

打開 工程屬性 -> 配置屬性 -> 常規,在右側的 項目默認值 -> 配置類型 中選擇「動態庫(.dll)」,這將使 VS 生成 dll 動態庫文件,而非 exe 可執行文件。

選擇 生成 -> 生成解決方案,生成 .dll 文件,將該文件複製到 Python 項目目錄下,將後綴改成 .pyd,獲得 hello_ext.pyd 文件,該文件即爲 Python 的庫文件,可直接經過 import 導入。

5、在 Python 中調用

咱們能夠像調用標準 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

版權聲明

做者:Wray Zheng
原文連接: www.codebelief.com/article/201…

相關文章
相關標籤/搜索