Windows系统下使用pybind11实现Python调用C++
前言
IDE:VS2022+Pycharm(只用VS也可以实现,即VS代替Pycharm生成python项目)
Python版本:本地Python3.9
为了运行一份python调用C++写的模块的代码,搜索各种操作方法实现以及请教他人,经过三四天之后终于成功。
实现步骤
第一步:下载pybind11
链接: GitHub下载地址
将pybind11下载到路径不包含中文的位置,此时的pybind11是header-only,只有头文件,不需要动态链接库
第二步:配置VS环境
1.VS新建C++空项目,右击项目->属性,设置平台为x64,配置选Debug,配置类型为.dll
2.在高级属性里面将目标文件扩展名改为.pyd
3.VC++目录中将包含目录设置为pybind11的路径以及接下来你要使用的Python编译器路径(这里设置的Python与你接下里使用的版本不同,将会报错,见踩坑合集),再将库目录设置一下
4.将调用的lib文件加入环境,这里我使用的是python3.9
到此,vs生成pyd文件前的环境就配置好了,可以尝试添加头文件#include<pybind11/pybind11.h>是否编译通过。
第三步: 生成pyd文件
上面环境配置好之后,填充你的C++代码,然后点击生成解决方案编译得到.pyd文件
右键项目在资源管理器中查看项目文件,在X64->Debug文件夹中找到目标pyd文件,将其复制。
第四步:配置Pycharm环境
pycharm新建项目,编辑配置
将Python解释器设置成和上面vs配置的python版本一致(在导入包的时候,也一定要注意Python解释器的设置!)
第五步:导入pyd文件
找到你的python解释器的lib/site-packages文件夹,将pyd粘贴到该文件夹下,在main.py中输入以下代码,将项目的搜索路径增加一条是该文件夹的路径:
import sys
sys.path.append('D:\\Python\\Lib\\site-packages') #pyd文件所在路径
然后导入与pyd文件同名的模块
import xxx # (与你的xxx.pyd同名)
注:正常情况下,导入语句应该没有红色波浪线,但是我在检查了所有可能踩过的坑之后发现没有问题还是会标红,不懂为什么就把后面用包的代码也完成之后运行,惊喜地发现居然运行成功!有点玄学哦·····
踩坑集合
导入pyd文件时提示“ImportError: No module named xxx”
造成这个问题的原因有很多:(前提是你成功编译生成了pyd文件)大致可以提供一下三个方面你去检查一下
1.vs配置的Python解释器版本与后面Python项目使用的Python解释器版本不同,甚至说你可以区设置成同一个(这个原因出错率最高!)
2.Pycharm搜索路径没有添加pyd所在路径,导致搜索不到,所以你可以按照上面第五步增加搜索路径
3.你的生成的pyd文件与导入的包不同名
vs2022提示“Error C2039: _invalid_parameter”
解决方法:打开pybind11.h,在第23行之后插入下面这行代码
#include <corecrt.h>
Pycharm使用设置添加Python解释器的包后,运行代码依然提示“ImportError: No module named xxx”
这里我忽略了导入包时,Python解释器的版本设置与项目运行环境配置的Python解释器不一致,甚至一度觉得是灵异事件···等我突然发现这个问题的时候我只想说一句:xx(哔掉——)
心得
为了运行成功python调用c++的项目代码,探索了几天的时间,踩了各种坑,才终于能够写出这篇教程,希望整理一下自己的思路再次加强对于这整个过程的理解。其实windows系统下的IDE给了我们很多方便(相比于命令行实现来说),同时也会失去一些机会去了解到你写出的代码真正实现的过程 。通过各种踩坑我对于使用IDE时应该注意的点有了更灵敏的感觉,对于使用命令行实现编译运行也有了进一步的兴趣和了解。踩坑越多,提升越多~