C++和Python混合编程之Pybind11的简单使用

本文介绍了如何使用Pybind11在C++和Python之间建立接口,包括环境配置、C++/Python相互调用的方法、代码实践以及注意事项,展示了如何通过Pybind11创建Python接口和调用Python代码实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++和Python混合编程之Pybind11的简单使用

一、简介

Pybind11是C++/Python混合编程的利器之一,是一个轻量级的只包含头文件的库,用于 Python 和 C++ 之间接口转换,可以为现有的 C++ 代码创建 Python 接口绑定。Pybind11 名字里的“11”表示它完全基于现代 C++ 开发(C++11 以上),所以没有兼容旧系统的负担。它使用了大量的现代 C++ 特性,不仅代码干净整齐,运行效率也更高。


二、平台环境

1、系统:Windows10
2、Python虚拟环境工具:Anaconda3
3、C++ IDE:Visual Studio 2022
4、Python版本:3.7.16


三、C++/Python相互调用的方法

简单介绍如何实现两种语言之间相互调用

1、Python调用C++代码: 通过调用动态库的方式完成,将C++代码编译生成动态库文件(Win下为.DLL),Python调用的话需要将库后缀改为(.pyd),然后将动态库拷贝到Python文件主目录,代码内导入库模块即可;

2、C++代码调用Python: 主要通过调用Python代码解释器来实现。


四、代码实践

用代码实例简单展现Pybind11的功能

1、基础环境搭建

1.1、安装Pybind11库

有多种安装方式,这里通过pip命令来安装,如果使用了虚拟环境,安装前记得激活相应的虚拟环境:

安装命令如下:

(py37) C:\Users\xxx> pip install pybind11

1.2、Visual Studio项目属性配置:

具体路径根据自己项目实际情况而定
1). 通用编译属性设置:

  • 属性–>常规–>常规属性–>配置类型:动态库(.dll)
  • 属性–>高级–>高级属性–>目标文件扩展名:.pyd

2). C/C++附加包含目录include:

  • 属性–>C/C++ -->常规–>附加包含目录:
  • D:\Anaconda3\envs\py37\include
  • D:\Anaconda3\envs\py37\Lib\site-packages\pybind11\include

3). 链接器附加库目录和库文件:

  • 属性–>链接器–>常规–>附加库目录:D:\Anaconda3\envs\py37\libs
  • 属性–>链接器–>输入–>附加依赖项:python3.lib,python37.lib

具体操作如下:
配置类型
目标文件扩展名
附加包含目录

附加库目录
附加依赖项


1.3、系统环境变量设置

1)、因为在C++调用Python代码过程中遇到错误,经过查资料找到了解决办法(stackoverflow讨论地址),以下环境具体路径根据自己项目实际情况而定。
2)、要在C++中调用Python解释器(py::scoped_interpreter guard{};),需要添加两个系统环境变量,以便Pybind11能够找到解释器位置:

  • PYTHONHOME:D:\Anaconda3\envs\py37
  • PYTHONPATH:D:\Anaconda3\envs\py37\Lib;D:\Anaconda3\envs\py37\Lib\site-packages;D:\Anaconda3\envs\py37\DLLs

3)、如果不设置这两个环境变量会出现以下错误:

  • Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
    Python runtime state: core initialized
    ModuleNotFoundError: No module named ‘encodings’

4)、设置完后重启电脑生效

错位描述
从打印的错误可以看出[PYTHONHOME,PYTHONPATH]两个系统环境变量未设置。

设置系统变量:
PYTHONHOME
PYTHONPATH
注意: 增加这两个环境变量后可能导致Anaconda3虚拟环境命令找不到,进而无法激活虚拟环境,如果出现则删除这两个环境变量即可(暂时没找到好的解决办法),删除后重启电脑。


2、Python使用C++代码动态库

演示两个流程:

  • C++编译动态库;
  • Python代码中调用动态库。
2.1、C++编译动态库

演示C++编译动态库以供Python调用

代码示例:

#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include <map>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>  // 转换标准容器必须的头文件

namespace py = pybind11;  // 名字空间别名,简化代码

class Point final
{
   
private:
	int x = 0;
public:
	Point() = default;
	~Point() = default;
	Point(int a) : x(a) {
   }
public:
	int get() const
	{
   
		return x;
	}

	void set(int a)
	{
   
		x = a;
	}
};

// 用lambda表达式来测试
PYBIND11_MODULE(pydemo, m)  // 定义Python模块pydemo
{
   
	m.doc() = "pybind11 demo doc";
	
	m.def("info",
		[]()
		{
   
			py::print("c++ version: ", __cplusplus);
		
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值