使用pybind11封装C++结构体作为参数的函数实现步骤

所属分类: 软件编程 / C 语言 阅读数: 46
收藏 0 赞 0 分享

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分

更多精彩内容其他人还在看

C语言数组入门之数组的声明与二维数组的模拟

这篇文章主要介绍了C语言数组入门之数组的声明与二维数组的模拟,数组学习的同时也要相应理解C语言指针的作用,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言中变量与其内存地址对应的入门知识简单讲解

这篇文章主要介绍了C语言中变量与其内存地址对应的入门知识简单讲解,同时这也是掌握指针部分知识的基础,需要的朋友可以参考下
收藏 0 赞 0 分享

讲解C语言编程中指针赋值的入门实例

这篇文章主要介绍了讲解C语言编程中指针赋值的入门实例,通过const int i与int *const pi这样两个例子来分析指针的赋值和地址指向,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言中的结构体的入门学习教程

这篇文章主要介绍了C语言中的结构体的入门学习教程,以struct语句定义的结构体是C语言编程中的重要基础,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言编程入门之程序头文件的简要解析

这篇文章主要介绍了C语言编程入门之程序头文件的简要解析,包括头文件重复包含问题等方面的说明,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言编程中的联合体union入门学习教程

这篇文章主要介绍了C语言编程中的联合体union入门学习教程,也是C语言入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言中数组作为函数的参数以及返回值的使用简单入门

这篇文章主要介绍了C语言中数组作为函数的参数以及返回值的使用简单入门,这里以一维数组作为基本条件进行例子讲解,需要的朋友可以参考下
收藏 0 赞 0 分享

MySQL的内存表的基础学习教程

这篇文章主要介绍了MySQL的内存表的基础学习教程,包括内存表的创建以及使用限制等等,需要的朋友可以参考下
收藏 0 赞 0 分享

C++中头文件的概念与基本编写方法

这篇文章主要介绍了C++中头文件的概念与基本编写方法,是C++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

jQuery移动页面开发中主题按钮的设计示例

这篇文章主要介绍了jQuery移动页面开发中主题按钮的设计示例,jQuery是当今最具人气的JavaScript开发类库,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多