• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見(jiàn)諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            Boost.Python

            Boost.PythonBoost 中的一個(gè)組件, 使用它能夠大大簡(jiǎn)化用 C++ 為 Python 寫(xiě)擴(kuò)展庫(kù)的步驟,提高開(kāi)發(fā)效率, 雖然目前它對(duì) Python 嵌入 C++ 的支持還不是很多, 但也能提供很大方便。另外, 華宇煜也編寫(xiě)了一份關(guān)于 Boost.Python 簡(jiǎn)明教程

            1 Boost 安裝簡(jiǎn)介

            在正式開(kāi)始使用 Boost.Python 之前, 我們必須先編譯 Boost。 首先到 Boost 的官方站點(diǎn) 下載 Boost 的源碼包, 把它們解壓到你喜歡的目錄,為編譯做好準(zhǔn)備。 另外, 在正式安裝 Boost.Python 之前, 我們必須先正確安裝 Python。

            1.1 Linux 下的編譯

            首先切換到 Boost 源碼所在的路徑, 執(zhí)行 ./configure 腳本,為配置腳本提供 Python 運(yùn)行環(huán)境相應(yīng)的參數(shù):

            ./configure --with-python=/usr/bin/python \
                        --with-python-version=2.4 \
                        --with-python-root=/usr
            

            然后, 和絕大部分 Linux 程序一行, 執(zhí)行 make 就可以開(kāi)始編譯了。編譯完畢后, 切換到 root 權(quán)限后再執(zhí)行 make install,把 Boost 相應(yīng)的頭文件和庫(kù)文件復(fù)制到相應(yīng)的地方, 就可以使用了。

            1.2 使用 MinGW + MSys 在 Windows 下的編譯

            首先需要編譯的是 Boost 的編譯工具 bjam, 直接到 bjam 所在目錄下, 即 Boost 源碼包所在目錄下的 \tools\build\jam_src, 執(zhí)行 build.bat mingw,稍等片刻, bjam.exe 就編譯好了。 把編譯好的 bjam.exe 復(fù)制到你的 %PATH% 路徑能夠直接找到的地方, 為后續(xù)的編譯工作做好準(zhǔn)備。

            接下來(lái), 切換到 Boost 源碼所在路徑, 執(zhí)行 bjam 進(jìn)行編譯。 我們需要提供關(guān)于 Python 的一些參數(shù), 變量 PYTHON_ROOT 指向 Python 運(yùn)行環(huán)境所在的目錄,變量 PYTHON_VERSION 的值為 Python 的版本號(hào), 如果你的 Python 安裝路徑與滇狐不同,請(qǐng)將相應(yīng)的變量修改為你機(jī)器上相應(yīng)的路徑, 編譯命令行如下:

            bjam.exe "-sTOOLS=mingw" "-sPYTHON_ROOT=E:\Python" "-sPYTHON_VERSION=2.4"
            

            編譯完畢后, 你將會(huì)在你的 C:\Boost 下找到編譯得到的 Boost 相應(yīng)頭文件與庫(kù)文件, 你可以根據(jù)你的需要將它移動(dòng)到別的地方備用。

            2 使用 Boost.Python 嵌入 Python 模塊到 C++

            Boost.Python 目前并沒(méi)有提供完整的將 Python 模塊嵌入到 C++ 的包裝庫(kù),因此許多工作我們還必須通過(guò) Python C API 來(lái)進(jìn)行。 但是, 利用 Boost.Python 中提供的一些模塊, 能夠給我們的工作帶來(lái)極大便利。

            2.1 修改模塊加載路徑,裝入 Python 模塊

            與任何一個(gè)其它 Python 嵌入 C/C++ 的程序一樣, 我們需要在第一條 #include 語(yǔ)句處含入 Python.h, 并在程序開(kāi)始時(shí)調(diào)用 Py_Initialize(),在程序結(jié)束時(shí)調(diào)用 Py_Finalize()

            接下來(lái), 我們便可以開(kāi)始準(zhǔn)備裝入 Python 模塊了。 為了讓 Python 解釋器能夠正確地找到 Python 模塊所在的位置, 我們需要將 Python 模塊所在的路徑添加到模塊搜索路徑中,添加搜索路徑的 Python 語(yǔ)句如下:

            import sys
            if not '/module/path' in sys.path:
                sys.path.append('/module/path')
            

            我們使用 Python C API 執(zhí)行類似的語(yǔ)句, 就能將模塊的搜索路徑添加到 Python 解釋器中。 添加了搜索路徑后, 就可以通過(guò) PyImport_ImportModule 函數(shù)加載 Python 模塊了。 PyImport_ImportModule 返回值是 PyObject *, 為了避免手工處理繁瑣的引用計(jì)數(shù)等問(wèn)題,我們求助于 Boost.Python 提供的 handle 模塊, 將 PyObject * 封裝起來(lái), 以方便使用, 代碼如下:

            #include <boost/python.hpp>
            
            ...
            
                boost::python::handle<>* _module; // Module handle.
                std::string path; // Path of the Python module.
                std::string module; // Module name.
            
            ...
            
                try
                {
                    PyRun_SimpleString("import sys");
                    PyRun_SimpleString((std::string("if not '") + path
                        + "' in sys.path: sys.path.append('" + path + "')").c_str());
                    _module = new boost::python::handle<>(
                        PyImport_ImportModule((char *) module));
                    ...
                }
                catch (...)
                {
                    PyErr_Print();
                    PyErr_Clear();
                    delete _module;
                    _module = NULL;
                    return false;
                }
            
            ...
            

            需要注意的是, 通過(guò) Python C API 加載的 Python 解釋器并沒(méi)有把當(dāng)前路徑列入默認(rèn)的搜索路徑中。因此, 即使你的 Python 模塊就存放在當(dāng)前路徑, 你也必須使用上面的代碼將當(dāng)前路徑添加到搜索路徑中之后,才能通過(guò) PyImport_ImportModule 加載到模塊。

            當(dāng) Python 模塊使用完畢或程序結(jié)束時(shí), 請(qǐng)使用 delete_module 指針釋放, handle 被釋放的時(shí)候會(huì)自動(dòng)釋放相應(yīng)的 Python 模塊并回收相應(yīng)資源。

            2.2 調(diào)用 Python 函數(shù)

            導(dǎo)入了 Python 模塊之后, 調(diào)用 Python 函數(shù)就非常容易了。 Boost.Python 里封裝了一個(gè)非常好用的模板函數(shù) boost::python::call_method,它可以替你處理調(diào)用函數(shù)時(shí)需要處理的種種細(xì)節(jié), 將你從 Python C API 中繁瑣的“將參數(shù)打包為 PyObject *”、 “構(gòu)造 Tuple”、 “傳遞 Tuple”、 “解包返回值”等工作中徹底解放出來(lái), 你只需要這樣:

                boost::python::call_method<返回值類型>(模塊指針, "Python 函數(shù)名",
                    參數(shù) 1, 參數(shù) 2, ...);
            

            模塊指針可以通過(guò)我們前面得到的 _moduleget 方法獲得, 例如:

            ...
                bool result;
                std::string config_file;
            
                ...
            
                try
                {
                    return boost::python::call_method<bool>(_module->get(), "initialize",
                        config_file);
                }
                catch (...)
                {
                    PyErr_Print();
                    PyErr_Clear();
                    ...
                }
            
            ...
            

            2.3 使用 Python 類對(duì)象

            使用 Python C API 調(diào)用 Python 函數(shù)和調(diào)用 Python 類對(duì)象是沒(méi)有太大區(qū)別的,我們只需要調(diào)用類的構(gòu)造方法, 得到一個(gè)類對(duì)象, 然后把該類的指針看做模塊指針,按照前面調(diào)用普通函數(shù)的方法調(diào)用類成員方法就可以了。 例如, 下列代碼從 _module 中創(chuàng)建了一個(gè) YukiSession 對(duì)象, 然后調(diào)用了其中的 on_welcome 方法。 除了展示調(diào)用類成員方法外, 這段代碼還展示了構(gòu)造 Python list 對(duì)象、 從 Python list 對(duì)象中獲取元素的方式。

                ...
            
                boost::python::handle<> _yukisession;
            
                ...
            
                // Retrieve the module handle and namespace handle.
                boost::python::object main_module(*_module);
                boost::python::object main_namespace = main_module.attr("__dict__");
            
                // Call the method and get the object handle.
                _yukisession = boost::python::handle<>((PyRun_String(
                    "YukiSession()", Py_eval_input,
                    main_namespace.ptr(), main_namespace.ptr())));
                ...
            
                // Compose a list.
                boost::python::list param;
                param.append(boost::python::str(_addr.get_host_addr()));
                param.append(boost::python::str());
            
                // Call the method and retrieve the result.
                // Method is equivalent to:
                // "bool __thiscall YukiSession::on_welcome(list param);"
                result = boost::python::call_method<bool>
                    (_yukisession.get(), "on_welcome", param);
                // Extract an item from a list.
                str = boost::python::call_method<std::string>
                    (param.ptr(), "__getitem__", 1);
            
                ...
            

            3 在嵌入的 Python 模塊中調(diào)用 C++ 程序

            通過(guò)動(dòng)態(tài)鏈接庫(kù)的方式使用 Boost.Python 導(dǎo)出 C++ 模塊到 Python 程序與在 C++ 可執(zhí)行程序中導(dǎo)出模塊給嵌入的 Python 解釋器, 編寫(xiě)程序的方式幾乎是完全相同的。因此這里只簡(jiǎn)單介紹導(dǎo)出普通函數(shù)的方法, 想詳細(xì)了解更多高級(jí)功能, 如導(dǎo)出 C++ 類、 導(dǎo)出可被 Python 重載的類等, 可以參看華宇煜的 Boost.Python 簡(jiǎn)明教程或官方 Boost.Python 文檔。

            3.1 導(dǎo)出 C++ 函數(shù)

            首先使用 BOOST_PYTHON_MODULE 宏定義需要導(dǎo)出給 Python 的模塊,然后用 boost::python::def 語(yǔ)句定義導(dǎo)出的函數(shù)、 參數(shù)列表以及 Doc String, 例如在下面的例子中, 我們導(dǎo)出了一個(gè) C++ 函數(shù) yukigettext,并重命名為 gettext

            const char *yukigettext(const char *id);
            
            BOOST_PYTHON_MODULE(yuki)
            {
                boost::python::def("gettext", yukigettext,
                    boost::python::args("id"), "Translate message.");
            }
            

            3.2 為 Python 初始化 C++ 模塊

            使用 BOOST_PYTHON_MODULE(name) 定義了 Python 模塊后,該宏會(huì)自動(dòng)生成一個(gè)函數(shù) initname, 我們需要在 Py_Initialize() 之后調(diào)用這個(gè)自動(dòng)生成的函數(shù), 初始化導(dǎo)出到 Python 的模塊。 例如我們剛才導(dǎo)出模塊用的宏 BOOST_PYTHON_MODULE(yuki), 因此初始化的時(shí)候就應(yīng)該調(diào)用 inityuki()

            ...
                Py_Initialize();
                inityuki();
            ...
            

            3.3 在 Python 模塊中調(diào)用 C++ 模塊

            此時(shí)我們?cè)?Python 模塊中只需要像普通的 Python 模塊那樣, 將導(dǎo)入的 C++ 模塊用 import 語(yǔ)句加載進(jìn)來(lái), 就可以調(diào)用了:

            import yuki
            
            ...
            
            print yuki.gettext("This is a test!")
            

            posted on 2008-04-25 17:54 肥仔 閱讀(2211) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Boost & STL

            久久亚洲精品视频| 精品久久久久国产免费 | 色欲综合久久躁天天躁| 99久久久精品免费观看国产| 日韩精品久久久久久久电影蜜臀| 久久人人爽人人爽人人片AV高清 | 国产高潮久久免费观看| 久久香蕉国产线看观看精品yw | 国产精品美女久久久m| 午夜精品久久久久久99热| 亚洲国产精品久久电影欧美| 久久人妻无码中文字幕| 色播久久人人爽人人爽人人片AV| 久久亚洲AV无码精品色午夜| 久久人人爽人人爽人人片AV东京热| 伊人色综合久久天天人守人婷| 免费一级欧美大片久久网| 久久精品无码免费不卡| 青青热久久国产久精品| 99久久免费国产精品特黄| 狠狠色婷婷久久一区二区| 色欲久久久天天天综合网精品 | 91久久国产视频| 国产日韩久久久精品影院首页| 国内精品久久久久影院网站| 久久亚洲色一区二区三区| 久久精品国产亚洲AV久| 97超级碰碰碰久久久久| 国产巨作麻豆欧美亚洲综合久久| 狠狠色综合久久久久尤物| 久久婷婷五月综合97色直播| 久久精品中文无码资源站| 国产成人综合久久久久久| 久久强奷乱码老熟女网站| 97久久国产露脸精品国产| 国产精品久久久久久搜索| 色综合久久中文字幕综合网| 色综合久久久久综合体桃花网| 亚洲午夜久久久精品影院| 久久精品国产色蜜蜜麻豆| 久久国产精品成人免费|