1. 程式人生 > 程式設計 >使用pybind11封裝C++結構體作為引數的函式實現步驟

使用pybind11封裝C++結構體作為引數的函式實現步驟

python呼叫C/C++有不少的方法,如boost.python,swig,ctypes,pybind11等,這些方法有繁有簡,而pybind11的優點是對C++ 11支援很好,API比較簡單,現在我們就簡單記下Pybind11的入門操作。

pybind11簡介

pybind11是一個輕量級的只包含標頭檔案的庫,它主要是用來在已有的 C++程式碼的基礎上做擴充套件,它的語法和目標非常像Boost.Python,但Boost.Python為了相容現有的基本所有的C++編譯器而變得非常複雜和龐大,而因此付出的代價是很多晦澀的模板技巧以及很多不必要的對舊版編譯器的支援。Pybind11摒棄了這些支援,它只支援python2.7以上以及C++ 11以上的編譯器,使得它比Boost.Python更加簡潔高效。

在C語言中,結構體(struct)指的是一種資料結構,是C語言中聚合資料型別(aggregate data type)的一類。結構體可以被宣告為變數、指標或陣列等,用以實現較複雜的資料結構。結構體同時也是一些元素的集合,這些元素稱為結構體的成員(member),且這些成員可以為不同的型別,成員一般用名字訪問。

結構體、結構體指標作為函式的引數應用的非常廣泛,本文介紹如何使用pybind11封裝C++結構體作為引數的函式。

一.需求分析

  • 現有名為 student 的結構體,有5個成員變數 name,Chinese,Mathematics,English和total ,建構函式通過name生成例項,成員函式 setName 可以給例項的name賦值;
  • calc 函式接收一個student例項作為引數,通過三門課程的分數計算出總分 total ;
  • 將student,calc封裝到包含一個student類和一個calc函式的python模組( abctest )中。

二.實現步驟

  1. 在標頭檔案中定義student結構體,並宣告calc函式;
  2. 在C++原始檔中實現func.cpp函式;
  3. 編寫pybind11封裝函式;
  4. 用python編寫setup指令碼;
  5. 編譯生成動態連結庫;
  6. 測試函式功能。

三.程式碼實現

在標頭檔案中定義student結構體,並宣告calc函式

//檔名:whjy.h
#include <string> 
using namespace std; 
struct student{ 
 string name; 
 int Chinese; 
 int Mathematics; 
 int English; 
 int total; 
 student(string n){ 
 this->name = n; 
 } 
 void setName(string stuName){ 
  this->name = stuName; 
 } 
}; 
void calc(struct student&);

在C++原始檔中實現func.cpp函式

//檔名:func.cpp
#include "whjy.h" 
#include <string> 
void calc(struct student& tyh){ 
 tyh.total = tyh.Chinese + tyh.Mathematics + tyh.English; 
}

編寫pybind11封裝函式

//檔名:func_wrapper.cpp
#include <pybind11/pybind11.h> 
#include "whjy.h" 
namespace py = pybind11; 
PYBIND11_MODULE(abctest,m){ 
 m.doc() = "simple example"; 
 
 py::class_<student>(m,"student") 
  .def(py::init<string>()) 
  .def("setName",&student::setName) 
  .def_readonly("name",&student::name) 
  .def_readwrite("Chinese",&student::Chinese) 
  .def_readwrite("Mathematics",&student::Mathematics) 
  .def_readwrite("English",&student::English) 
  .def_readwrite("total",&student::total); 
 m.def("calc",&calc); 
}

用python編寫setup指令碼

#檔名:setup.py
from setuptools import setup,Extension 
 
functions_module = Extension( 
 name = 'abctest',sources = ['func.cpp','func_wrapper.cpp'],include_dirs = [r'D:\software\pybind11-master\include',r'D:\software\Anaconda\include'] 
) 
 
setup(ext_modules = [functions_module])

編譯生成動態連結庫

在命令列執行 python setup.py build_ext --inplace ,在當前路徑下生成pyd動態庫。

測試函式功能

#檔名:test.py
import abctest 
s = abctest.student("小明") 
s.Chinese = 100 
s.Mathematics = 110 
s.English =120 
abctest.calc(s) 
print(s.name + ":" + str(s.total) + "分") 
print("----------------------") 
s.setName("小紅") 
print(s.name + ":" + str(s.total) + "分")

output:
小明:330分
----------------------
小紅:330分

總結

到此這篇關於使用pybind11封裝C++結構體作為引數的函式的實現步驟的文章就介紹到這了,更多相關pybind11封裝C++結構體引數函式內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!