當#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_readwrite
ordef_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...