欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

pybind11: C++ 工程提供 Python 接口的實(shí)例代碼

 更新時(shí)間:2020年09月04日 08:32:08   作者:GoCodingInMyWay  
這篇文章主要介紹了pybind11: C++ 工程如何提供 Python 接口,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

C/C++ 工程提供 Python 接口,有利于融合進(jìn) Python 的生態(tài)?,F(xiàn)在 Python 在應(yīng)用層,有其得天獨(dú)厚的優(yōu)勢(shì)。尤其因?yàn)槿斯ぶ悄芎痛髷?shù)據(jù)的推波助瀾, Python 現(xiàn)在以及未來(lái),將長(zhǎng)期是最流行的語(yǔ)言之一。

那 C/C++ 怎么提供 Python 接口呢?

  • ctypes: C 與 Python 綁定, Python 內(nèi)建模塊
  • Boost.Python: C++ 與 Python 綁定, Boost 模塊
  • pybind11: C++11 與 Python 綁定, 減去了舊 C++ 支持,更輕量化

本文將介紹 pybind11 的環(huán)境準(zhǔn)備與入門(mén)使用。

pybind11: https://github.com/pybind/pybind11

環(huán)境準(zhǔn)備

pybind11 是一個(gè) header-only 的庫(kù),換句話說(shuō),只需要 C++ 項(xiàng)目里直接 include pybind11 的頭文件就能使用。

這里則介紹如何于 CMake 里引入 pybind11 。而更多編譯系統(tǒng)的介紹,可見(jiàn)官方文檔 Build systems 。

獲取 pybind11

可以 git submodule 添加子模塊,最好固定為某個(gè)版本:

git submodule add https://github.com/pybind/pybind11.git third_party/pybind11-2.5.0
cd third_party/pybind11-2.5.0/
git checkout tags/v2.5.0

或者,直接獲取源碼,放進(jìn)相應(yīng)子目錄即可。

添加進(jìn) CMake

CMakeLists.txtadd_subdirectory pybind11 的路徑,再用其提供的 pybind11_add_module 就能創(chuàng)建 pybind11 的模塊了。

cmake_minimum_required(VERSION 3.1)
project(start-pybind11 VERSION 0.1.0 LANGUAGES C CXX)

set(MY_PYBIND ${MY_CURR}/third_party/pybind11-2.5.0)

add_subdirectory(${MY_PYBIND})
pybind11_add_module(example_pb example_pb.cpp)

如果想在已有 C++ 動(dòng)態(tài)庫(kù)上擴(kuò)展 pybind11 綁定,那么 target_link_libraries 鏈接該動(dòng)態(tài)庫(kù)就可以了。

target_link_libraries(example_pb PUBLIC example)

綁定一個(gè)函數(shù)

我們先實(shí)現(xiàn)一個(gè) add 函數(shù),

int add(int i, int j) {
 return i + j;
}

為了簡(jiǎn)化工程,可以直接實(shí)現(xiàn)在 example_pb.cpp 里,

#include <pybind11/pybind11.h>

namespace py = pybind11;

int add(int i, int j) {
 return i + j;
}

PYBIND11_MODULE(example_pb, m) {
 m.doc() = "example_pb bindings";

 m.def("add", &add, "A function which adds two numbers");
}

之后,于 CMakeLists.txt 所在目錄,執(zhí)行 cmake 編譯就完成了。

示例代碼

綁定一個(gè)類(lèi)

我們先實(shí)現(xiàn)一個(gè)定時(shí)觸發(fā)器的類(lèi)。使用如下:

#include <iostream>

#include "tick.h"

int main(int argc, char const *argv[]) {
 (void)argc;
 (void)argv;

 Tick tick(500, 5000);

 tick.SetTickEvent([&tick](std::int64_t elapsed_ms) {
 std::cout << "elapsed: " << elapsed_ms << " ms" << std::endl;
 if (elapsed_ms >= 2000) {
  tick.Stop();
 }
 });

 tick.Start();
 tick.WaitLifeOver();
 return 0;
}

運(yùn)行結(jié)果:

$ ./_output/bin/cpp_thread_callback/tick_test
elapsed: 0 ms
elapsed: 500 ms
elapsed: 1000 ms
elapsed: 1500 ms
elapsed: 2000 ms

該類(lèi)的聲明如下:

using TickEvent = std::function<void(std::int64_t elapsed_ms)>;
using TickRunCallback = std::function<void()>;

class Tick {
 public:
 using clock = std::chrono::high_resolution_clock;

 Tick(std::int64_t tick_ms,
  std::int64_t life_ms = std::numeric_limits<std::int64_t>::max());
 Tick(TickEvent tick_event, std::int64_t tick_ms,
  std::int64_t life_ms = std::numeric_limits<std::int64_t>::max(),
  TickRunCallback run_beg = nullptr,
  TickRunCallback run_end = nullptr);
 virtual ~Tick();

 bool IsRunning() const;

 void Start();
 void Stop(bool wait_life_over = false);

 const std::chrono::time_point<clock> &GetTimeStart() const;

 void SetTickEvent(TickEvent &&tick_event);
 void SetTickEvent(const TickEvent &tick_event);

 void SetRunBegCallback(TickRunCallback &&run_beg);
 void SetRunBegCallback(const TickRunCallback &run_beg);

 void SetRunEndCallback(TickRunCallback &&run_end);
 void SetRunEndCallback(const TickRunCallback &run_end);

 void WaitLifeOver();

 protected:
 // ...
};

然后, pybind11 綁定實(shí)現(xiàn)如下:

#include <pybind11/pybind11.h>
#include <pybind11/chrono.h>
#include <pybind11/functional.h>

#include <memory>

#include "cpp/cpp_thread_callback/tick.h"

namespace py = pybind11;
using namespace pybind11::literals; // NOLINT

PYBIND11_MODULE(tick_pb, m) {
 m.doc() = "tick_pb bindings";

 py::class_<Tick, std::shared_ptr<Tick>>(m, "Tick")
 .def(py::init<std::int64_t, std::int64_t>())
 .def(py::init<TickEvent, std::int64_t, std::int64_t,
     TickRunCallback, TickRunCallback>())
 .def_property_readonly("is_running", &Tick::IsRunning)
 .def("start", &Tick::Start)
 .def("stop", &Tick::Stop, "wait_life_over"_a = false)
 .def("get_time_start", &Tick::GetTimeStart)
 .def("set_tick_event", [](Tick &self, const TickEvent &tick_event) {
  self.SetTickEvent(tick_event);
 })
 .def("set_run_beg_callback", [](Tick &self,
  const TickRunCallback &run_beg) {
  self.SetRunBegCallback(run_beg);
 })
 .def("set_run_end_callback", [](Tick &self,
  const TickRunCallback &run_end) {
  self.SetRunEndCallback(run_end);
 })
 .def("wait_life_over", &Tick::WaitLifeOver,
  py::call_guard<py::gil_scoped_release>());
}

編譯出動(dòng)態(tài)庫(kù)后,把路徑添加進(jìn) PYTHONPATH

export PYTHONPATH=<path>:$PYTHONPATH

# 依賴其他動(dòng)態(tài)庫(kù)的話,把路徑添加進(jìn) LIBRARY_PATH
# Linux
export LD_LIBRARY_PATH=<path>:$LD_LIBRARY_PATH
# macOS
export DYLD_LIBRARY_PATH=<path>:$DYLD_LIBRARY_PATH

之后,就可以于 Python 里調(diào)用了:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# pylint: disable=missing-docstring, import-error
import tick_pb as tick

def _main():
 t = tick.Tick(lambda elapsed_ms: print(f"elapsed: {elapsed_ms} ms"),
    500, 1000,
    lambda: print("run beg"), lambda: print("run end"))
 t.start()
 t.wait_life_over()

if __name__ == "__main__":
 _main()

運(yùn)行結(jié)果:

$ python src/pybind/cpp_thread_callback/tick_test.py
run beg
elapsed: 0 ms
elapsed: 500 ms
elapsed: 1000 ms
run end

示例代碼

運(yùn)行示例代碼

獲取代碼,

git clone https://github.com/ikuokuo/start-pybind11.git

# 獲取子模塊
cd start-pybind11/
git submodule update --init

編譯安裝,

# 依賴 cmake

cd start-pybind11/
make install

編譯結(jié)果,

$ tree _install
_install
├── bin
│ └── cpp_thread_callback
│  └── tick_test
└── lib
 ├── cpp_thread_callback
 │ ├── libtick.0.1.0.dylib
 │ ├── libtick.0.1.dylib -> libtick.0.1.0.dylib
 │ ├── libtick.dylib -> libtick.0.1.dylib
 │ ├── tick_pb.0.1.0.cpython-37m-darwin.so
 │ ├── tick_pb.0.1.cpython-37m-darwin.so -> tick_pb.0.1.0.cpython-37m-darwin.so
 │ └── tick_pb.cpython-37m-darwin.so -> tick_pb.0.1.cpython-37m-darwin.so
 └── first_steps
  ├── first_steps_pb.0.1.0.cpython-37m-darwin.so
  ├── first_steps_pb.0.1.cpython-37m-darwin.so -> first_steps_pb.0.1.0.cpython-37m-darwin.so
  ├── first_steps_pb.cpython-37m-darwin.so -> first_steps_pb.0.1.cpython-37m-darwin.so
  ├── libfirst_steps.0.1.0.dylib
  ├── libfirst_steps.0.1.dylib -> libfirst_steps.0.1.0.dylib
  └── libfirst_steps.dylib -> libfirst_steps.0.1.dylib

5 directories, 13 files

添加路徑,

$ source setup.bash first_steps cpp_thread_callback
DYLD_LIBRARY_PATH, PYTHONPATH
+ /Users/John/Workspace/Self/ikuokuo/start-pybind11/_install/lib/first_steps
+ /Users/John/Workspace/Self/ikuokuo/start-pybind11/_install/lib/cpp_thread_callback

運(yùn)行示例,

$ python src/pybind/cpp_thread_callback/tick_test.py
run beg
elapsed: 0 ms
elapsed: 500 ms
elapsed: 1000 ms
run end

結(jié)語(yǔ)

Go coding!

總結(jié)

到此這篇關(guān)于pybind11: C++ 工程提供 Python 接口的文章就介紹到這了,更多相關(guān)pybind11: C++ 工程如何提供 Python 接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)模擬銀行系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)模擬銀行系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)模擬銀行系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 標(biāo)準(zhǔn)CSV格式的介紹和分析以及解析算法實(shí)例詳解

    標(biāo)準(zhǔn)CSV格式的介紹和分析以及解析算法實(shí)例詳解

    這篇文章主要介紹了標(biāo)準(zhǔn)CSV格式的介紹和分析以及解析算法實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • C語(yǔ)言冷知識(shí)之預(yù)處理字符串操作符詳解

    C語(yǔ)言冷知識(shí)之預(yù)處理字符串操作符詳解

    當(dāng)年學(xué)習(xí)C語(yǔ)言的第一門(mén)課就提到過(guò)標(biāo)記(Token)的概念,不過(guò),相信在多年之后你再次聽(tīng)到這個(gè)術(shù)語(yǔ)時(shí)會(huì)一臉懵逼,比如我。因此特地翻了翻資料,整理下來(lái)這些筆記,希望對(duì)大家有所幫助
    2022-11-11
  • 關(guān)于C++使用指針 堆和棧的區(qū)別分析

    關(guān)于C++使用指針 堆和棧的區(qū)別分析

    本篇文章小編為大家介紹,關(guān)于C++使用指針 堆和棧的區(qū)別分析。需要的朋友參考下
    2013-04-04
  • C++字符串提取和分割的多種方法

    C++字符串提取和分割的多種方法

    在C++編程中,字符串處理是一個(gè)常見(jiàn)的任務(wù),尤其是在需要從字符串中提取特定數(shù)據(jù)時(shí),本文將詳細(xì)探討如何使用C++標(biāo)準(zhǔn)庫(kù)中的工具來(lái)提取和分割字符串,并分析不同方法的適用場(chǎng)景和優(yōu)缺點(diǎn),我們將通過(guò)多個(gè)示例代碼逐步講解,幫助讀者掌握字符串處理的技巧,需要的朋友可以參考下
    2025-03-03
  • C語(yǔ)言實(shí)現(xiàn)二叉樹(shù)的搜索及相關(guān)算法示例

    C語(yǔ)言實(shí)現(xiàn)二叉樹(shù)的搜索及相關(guān)算法示例

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)二叉樹(shù)的搜索及相關(guān)算法,結(jié)合具體實(shí)例形式分析了基于C語(yǔ)言創(chuàng)建、遍歷、搜索等相關(guān)算法與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06
  • C語(yǔ)言實(shí)現(xiàn)圖的鄰接矩陣存儲(chǔ)操作

    C語(yǔ)言實(shí)現(xiàn)圖的鄰接矩陣存儲(chǔ)操作

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)圖的鄰接矩陣存儲(chǔ)操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • C語(yǔ)言設(shè)計(jì)一個(gè)閃閃的圣誕樹(shù)

    C語(yǔ)言設(shè)計(jì)一個(gè)閃閃的圣誕樹(shù)

    本文使用C語(yǔ)言基礎(chǔ)知識(shí)在控制臺(tái)打印一個(gè)圣誕樹(shù)效果,真的很簡(jiǎn)單哦,一起通過(guò)本文學(xué)習(xí)吧
    2016-12-12
  • 詳解C++?左值引用與?const?關(guān)鍵字

    詳解C++?左值引用與?const?關(guān)鍵字

    這篇文章主要介紹了C++?左值引用與?const?關(guān)鍵字,左值引用是已定義的變量的別名,其主要用途是用作函數(shù)的形參,將?const?關(guān)鍵字用于左值引用時(shí),其在初始化時(shí)可接受的賦值形式變得更加廣泛了,這里來(lái)總結(jié)一下,需要的朋友可以參考下
    2022-09-09
  • C++如何采用Daemon進(jìn)行后臺(tái)程序的部署

    C++如何采用Daemon進(jìn)行后臺(tái)程序的部署

    這篇文章主要介紹了C++采用Daemon進(jìn)行后臺(tái)程序的部署,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04

最新評(píng)論