用pybind11封装C++结构体作为参数的函数

在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   
  
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   
  
void calc(struct student& tyh){  
    tyh.total = tyh.Chinese + tyh.Mathematics + tyh.English;  
}
  • 编写pybind11封装函数
//文件名:func_wrapper.cpp
#include   
#include "whjy.h"  
  
namespace py = pybind11;  
  
PYBIND11_MODULE(abctest, m){  
    m.doc() = "simple example";  
  
    py::class_(m, "student")  
        .def(py::init())  
        .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分

你可能感兴趣的:(python,c++)