廣告
| 使用C++擴充Python |
|
|
|
| 作者是 Victor | |
| 週三, 11 二月 2009 21:09 | |
使用C++擴充Python使用C++的Boost.Python括充一個Python的模組教學 為什麼要擴充Python?時常有人問Python到底能做什麼,我的回答是,看你要拿Python來做什麼,因為Python可以用C語言擴充,這表示C語言能做到的事都可以由 Python,現有的函式庫如果辦不到,大不了你自己寫一個,這不僅僅是只有這樣的好處而已,很多時候我們希望能有Python的彈性、可讀性等各種好 處,但又有C語言的高效率,就可以將整個程式中較吃重的工作用C語言寫成module供Python使用,同時兼俱彈性與效率 使用的工具我們要使用的是C++的Boost函式庫裡的Python模組,它是用來包裝C++供Python使用的函式庫,不使用這個函式庫的話,你必須使用Python提供的C語言API自行包裝,在這裡我們示範如何使用Boost.Python來包裝成模組讓Python使用 在開始之前,你必須確定你有安裝Boost的函式庫,如果沒有的話,請到Boost的官方網站自行下載並編譯或安裝,如果不知道怎麼編譯可以考慮下載事先編譯完成的版本 第一個簡單的例子我們參考Boost官方網站的 文件,一個簡單的模組hello.cpp char const* greet()
{
return "hello, world";
}
#include
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
有了Boost.Python的幫忙,用C++擴充Python會是一件超級簡單的事,相較於這個例子,編譯看起來就麻煩得多了 進行編譯Boost.Python的模組通常都使用bjam來編譯,什麼是bjam呢? 它是boost的一套編譯系統,你可以下載原始碼自行編譯,同樣的如果你不知道如何自行編譯的話,可以 下載事先編譯的版本,在這裡我們通常選ntx86,如果你用的是PC的話,然後確定你的bjam.exe的目錄在PATH的環境變數中,或著你可以直接把bjam.exe放在my_module.cpp的同一個資料夾下
接著我們必須建立bjam的編譯檔案,你可以在boost的目錄"\libs\python\example\quickstart"下面找到它們,複製到你的模組同樣的資料夾下並修改,分別是 boost-build.jam # Copyright David Abrahams 2006. Distributed under the Boost # Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # Edit this path to point at the tools/build/v2 subdirectory of your # Boost installation. Absolute paths work, too. boost-build ../../../../tools/build/v2 ; Jamroot # Copyright David Abrahams 2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Specify the path to the Boost project. If you move this project,
# adjust the path to refer to the Boost root directory.
use-project boost
: ../../../.. ;
# Set up the project-wide requirements that everything uses the
# boost_python library defined in the project whose global ID is
# /boost/python.
project boost-python-quickstart
: requirements <library>/boost/python//boost_python
;
# Make the definition of the python-extension rule available
import python ;
# Declare a Python extension called hello.
python-extension extending : extending.cpp ;
# Declare an executable called embedding that embeds Python
exe embedding : embedding.cpp /python//python ;
import testing ;
# Declare a test of the extension module
testing.make-test run-pyd : extending test_extending.py : : test_ext ;
# Declare a test of the embedding application
testing.run embedding
: # any ordinary arguments
: script.py # any arguments that should be treated as relative paths
: # requirements
: test_embed ; # name of test
# Create a "test" target that runs all the tests
alias test : test_ext test_embed ;
# make sure the tests don't run by default
explicit test_ext test_embed test ;
;
兩個檔案,但是因為這些檔案的內容並不能直接使用,需要做一點修改,以下是我們修改的版本 boost-build.jam # Copyright David Abrahams 2006. Distributed under the Boost # Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # Edit this path to point at the tools/build/v2 subdirectory of your # Boost installation. Absolute paths work, too. boost-build C:/boost/boost_1_35_0/tools/build/v2 ; 這個檔案我們修改了boost-build,設為絕對的路徑,你應該修改它成你安裝boost的位置 Jamroot # Copyright David Abrahams 2006. Distributed under the Boost # Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # Specify the path to the Boost project. If you move this project, # adjust the path to refer to the Boost root directory. use-project boost : I:/boost/boost_1_36_0 ; # Set up the project-wide requirements that everything uses the # boost_python library defined in the project whose global ID is # /boost/python. project boost-python-quickstart : requirements <library>/boost/python//boost_python <threading>multi ; # Make the definition of the python-extension rule available import python ; # Declare a Python extension called hello. python-extension hello_ext : hello.cpp 我們修改了use-project boost的專案目錄位置,改成你放置my_module.cpp的地方,然後還有python-extension改成我們的模組名稱和.cpp檔位 置,除此之外我們還刪除了建置測試用的部份,以上兩個檔案都應放在和my_module.cpp同一個目錄下,準備完成就可以開始進行編譯,進入cmd, 切換目錄,執行bjam cd c:\python_tutorial bjam 如果沒有錯誤,應該該會產生一個hello_ext.pyd的檔案,這時只要將它copy到Python的library目錄,或是你Python模組執行的目錄,除此之外還有boost相對應的python的DLL檔,就可以直接使用 import hello_ext print hello_ext.greet() 像這樣就會印出hello, world的字樣,如果你不想使用shared的方式link到Boost.Python以及不想產生debug資訊,你可以選擇使用下列指令 bjam release link=static 更多的參數指令可以在這裡被找到 http://www.boost.org/doc/tools/build/doc/html/bbv2/advanced/invocation.html 如果你有需要增加include的目錄或是要link的lib,可以將project 的 requirements部份改寫 project boost-python-quickstart : requirements <library>/boost/python//boost_python <threading>multi <library>test.lib <include>header/util ; 詳細參數請參考 http://www.boost.org/doc/tools/build/doc/html/bbv2/advanced/builtins/features.html 常見錯誤
如果你在import時遇到下列錯誤 ImportError: dynamic module does not define init function (inithello) 那通常是你在BOOST_PYTHON_MODULE定義的名稱和在Jamroot定義的不同所引起的
|
|
| 最近更新在 週四, 12 二月 2009 01:38 |
核心是 Joomla!. Designed by: Free Joomla Theme, whois protect. Valid XHTML and CSS.


