pybind11使用教程筆記 4 2

2021-10-23 06:45:44 字數 2562 閱讀 4087

#include,std::vector<>/std::deque<>/std::list<>/std::array<>, std::set<>/std::unordered_set<>, and std::map<>/std::unordered_map<>python list, set and dict data structures會自動進行轉換。std::pair<> and std::tuple<>在標頭檔案pybind11/pybind11.h 中支援開箱即用。

這種資料型別轉換的主要缺點是 必須進行記憶體拷貝,會影響程式的語法和效能。

****** opaque types

pybind11很依賴template matching mechanism,來將stl資料結構(比如:vector, linked list, hash table 等資料結構)中的資料和引數 進行轉換和返回。

然而這種內部轉換的方法因為涉及拷貝操作,這不允許進行引用呼叫。這意味著什麼呢?如下例:

v.push_back(1);}

從python中呼叫如上函式:

>>> v = [5, 6]

>>> print(v)

[5, 6]

如上所示,當將stl資料結構通過引用呼叫進行傳遞,c++中資料的改動並沒有傳回python端。類似的,在用def_readwriteordef_readonly來暴露c++ stl資料結構的時候也會出現這樣的問題。

/* ... definition ... */

class

myclass

;

/* ... binding code ... */

py::class_

(m,"myclass").

def(py::init<

>()

).def_readwrite

("contents"

,&myclass::contents)

;

這種情況下,properties被設定為可讀可寫,但是python實際使用時不可寫

>>

> m = myclass(

)>>

> m.contents =[5

,6]>>

>

print

(m.contents)[5

,6]>>7)

>>

>

print

(m.contents)[5

,6]

最後,當資料非常大的時候,拷貝操作非常耗費資源。

為了處理這種情況,pybind11 提供了pybind11_make_opaque(t)的巨集,這個巨集使得型別轉換不依賴於template-based conversion machinery of types。

這樣一來是他們不透明。opaque types物件are never inspected or extracted, 因而可以通過引用進行傳遞。如將std::vector轉為opaque型別, 在編寫binding code前,先新增如下宣告:

pybind11_make_opaque(std::vector)

這個巨集必須在程式頂部進行宣告,並且不能在namespcae當中,因為這句巨集會對模板的初始化進行過載,如果有多個編譯單元,那麼需要在每個原始檔中使用std::vector前都要有這句巨集,通常是共用乙個標頭檔案。

通常還會有乙個class 來bind相關的operation,以便python能否呼叫相關操作。

py::class_int>>

(m,"intvector").

def(py::init<

>()

).def(

"clear"

,&std::vector<

int>

::clear)

.def

("pop_back"

,&std::vector<

int>

::pop_back)

.def

("__len__",[

](const std::vector<

int>

&v))

.def

("__iter__",[

](std::vector<

int>

&v), py::keep_alive<0,

1>()

)/* keep vector alive while iterator is used */

// ....

pybind11 原始碼中 tests/test_opaque_types.cpp 有使用opaque完整的例子,且細節比較豐富。

pybind11以及打包學習

最近在看fasttext,看到使用pybind11把c 封裝了一下,然後打包後安裝,python可以直接呼叫,非常方便,有點興趣,手動試了簡單例子,本篇沒啥乾貨,簡單記錄下實現過程。c c 都是用pybind11封裝,可以直接用pip安裝即可,官方給出的入門示例十分簡單 include int ad...

python呼叫c 介面 pybind11

pybind11是乙個將c 介面轉接給python的庫,它支援c 11標準的編譯器。這裡我做了乙個簡單的實驗,主要是驗證將eigen matrixxf型別對映到numpy ndarray型別,這樣就可以在python愉快地呼叫c 函式了。完整 見 首先,python指令碼 usr bin env p...

pybind11 工具轉換 C 介面

pybind11 是乙個輕量級的 header only 庫,可以將 c 型別暴露給 python,反之亦然,主要用來將 c 介面轉成 python。apt install python3 devgit clone git submodule update init recursive cmakel...