<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 9.5 使用pybind11構建C++和Python項目 **NOTE**:*此示例代碼可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-9/recipe-05 中找到,其中有一個C++示例。該示例在CMake 3.11版(或更高版本)中是有效的,并且已經在GNU/Linux、macOS和Windows上進行過測試。* 前面的示例中,我們使用Boost.Python與C(C++)接口。本示例中,我們將嘗試使用pybind11將Python與C++接口。其實現利用了C++11的特性,因此需要支持C++11的編譯器。我們將演示在配置時如何獲取pybind11依賴和構建我們的項目,包括一個使用FetchContent方法的Python接口,我們在第4章第3節和第8章第4節中有過討論。在第11章第2節時,會通過PyPI發布一個用CMake/pybind11構建的C++/Python項目。屆時將重新討論這個例子,并展示如何打包它,使它可以用pip安裝。 ## 準備工作 我們將保持`account.cpp`不變,只修改`account.cpp`: ```c++ #pragma once #include <pybind11/pybind11.h> class Account { public: Account(); ~Account(); void deposit(const double amount); void withdraw(const double amount); double get_balance() const; private: double balance; }; namespace py = pybind11; PYBIND11_MODULE(account, m) { py::class_<Account>(m, "Account") .def(py::init()) .def("deposit", &Account::deposit) .def("withdraw", &Account::withdraw) .def("get_balance", &Account::get_balance); } ``` 按照pybind11文檔的方式,通過CMake構建(https://pybind11.readthedocs.io/en/stable/compile )。并使用`add_subdirectory`將pybind11導入項目。但是,不會將pybind11源代碼顯式地放到項目目錄中,而是演示如何在配置時使用`FetchContent` (https://cmake.org/cmake/help/v3.11/module/FetchContent.html )。 為了在下一個示例中更好地重用代碼,我們還將把所有源代碼放到子目錄中,并使用下面的項目布局: ```shell . ├── account │ ├── account.cpp │ ├── account.hpp │ ├── CMakeLists.txt │ └── test.py └── CMakeLists.txt ``` ## 具體實施 讓我們詳細分析一下這個項目中,各個`CMakeLists.txt`文件的內容: 1. 主`CMakeLists.txt`文件: ```cmake # define minimum cmake version cmake_minimum_required(VERSION 3.11 FATAL_ERROR) # project name and supported language project(recipe-05 LANGUAGES CXX) # require C++11 set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) ``` 2. 這個文件中,查詢了用于測試的Python解釋器: ```cmake find_package(PythonInterp REQUIRED) ``` 3. 然后,包含`account`子目錄: ```cmake add_subdirectory(account) ``` 4. 定義單元測試: ```cmake # turn on testing enable_testing() # define test add_test( NAME python_test COMMAND ${CMAKE_COMMAND} -E env ACCOUNT_MODULE_PATH=$<TARGET_FILE_DIR:account> ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/account/test.py ) ``` 5. `account/CMakeLists.txt `中,在配置時獲取pybind11的源碼: ```cmake include(FetchContent) FetchContent_Declare( pybind11_sources GIT_REPOSITORY https://github.com/pybind/pybind11.git GIT_TAG v2.2 ) FetchContent_GetProperties(pybind11_sources) if(NOT pybind11_sources_POPULATED) FetchContent_Populate(pybind11_sources) add_subdirectory( ${pybind11_sources_SOURCE_DIR} ${pybind11_sources_BINARY_DIR} ) endif() ``` 6. 最后,定義Python模塊。再次使用模塊選項`add_library`。并將庫目標的前綴和后綴屬性設置為`PYTHON_MODULE_PREFIX`和`PYTHON_MODULE_EXTENSION`,這兩個值由pybind11適當地推斷出來: ```cmake add_library(account MODULE account.cpp ) target_link_libraries(account PUBLIC pybind11::module ) set_target_properties(account PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" SUFFIX "${PYTHON_MODULE_EXTENSION}" ) ``` 7. 進行測試: ```shell $ mkdir -p build $ cd build $ cmake .. $ cmake --build . $ ctest Start 1: python_test 1/1 Test #1: python_test ...................... Passed 0.04 sec 100% tests passed, 0 tests failed out of 1 Total Test time (real) = 0.04 sec ``` ## 工作原理 pybind11的功能和使用與Boost.Python非常類似。pybind11是一個更輕量級的依賴——不過需要編譯器支持C++11。` account.hpp`中的接口定義與之前的示例非常類似: ```c++ #include <pybind11/pybind11.h> // ... namespace py = pybind11; PYBIND11_MODULE(account, m) { py::class_<Account>(m, "Account") .def(py::init()) .def("deposit", &Account::deposit) .def("withdraw", &Account::withdraw) .def("get_balance", &Account::get_balance); } ``` 同樣,我們可以了解到Python方法是如何映射到C++函數的。解釋`PYBIND11_MODULE`庫是在導入的目標` pybind11::module `中定義,使用以下代碼包括了這個模塊: ```cmake add_subdirectory( ${pybind11_sources_SOURCE_DIR} ${pybind11_sources_BINARY_DIR} ) ``` 與之前的示例有兩個不同之處: * 不需要在系統上安裝pybind11 * `${pybind11_sources_SOURCE_DIR}`子目錄,包含pybind11的`CMakelist.txt`中,在我們開始構建項目時,這個目錄并不存在 這個挑戰的解決方案是用`FetchContent`,在配置時獲取pybind11源代碼和CMake模塊,以便可以使用`add_subdirectory`引用。使用`FetchContent`模式,可以假設pybind11在構建樹中可用,并允許構建和鏈接Python模塊: ```cmake add_library(account MODULE account.cpp ) target_link_libraries(account PUBLIC pybind11::module ) ``` 使用下面的命令,確保Python模塊庫得到一個定義良好的前綴和后綴,并與Python環境兼容: ```cmake set_target_properties(account PROPERTIES PREFIX ${PYTHON_MODULE_PREFIX} SUFFIX ${PYTHON_MODULE_EXTENSION} ) ``` 主`CMakeLists.txt`文件的其余部分,都在執行測試(與前一個示例使用相同的`test.py`)。 ## 更多信息 我們可以將pybind11源代碼包含在項目源代碼存儲庫中,這將簡化CMake結構,并消除在編譯時對pybind11源代碼進行網絡訪問的要求。或者,我們可以將pybind11源路徑定義為一個Git子模塊(https://git-scm.com/book/en/v2/Git-Tools-Submodules ),以應對pybind11源依賴項的更新。 在示例中,我們使用`FetchContent`解決了這個問題,它提供了一種非常緊湊的方法來引用CMake子項目,而不是顯式地跟蹤它的源代碼。同樣,我們也可以使用超級構建的方法來解決這個問題(參見第8章)。 要查看如何簡單函數、定義文檔注釋、映射內存緩沖區等進階閱讀,請參考pybind11文檔:https://pybind11.readthedocs.io
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看