使用Pybind11可以让python来调用C++,使用python本身的库也可以让C++来调用python函数,以实现C++和python相互调用,实际上我们还可以同时调试C++和Python(混合模式调试,正如封面展示这样),混合模式调试要使用Visual Studio调python,后面博客会介绍C++调用python的传参和混合模式调试,这篇博客主要先介绍C++调用python的流程:
不建议使用Anaconda的python,建议使用系统自带python或自己从python官网下载的python(查到很多教程都反映Anaconda的python少东西或者调用不成功,可以不用Anaconda的话能减少踩坑机率)。
CMake
如果使用cmake的话,就不用管下面的windows/linux了,在所有平台都是一样的,也非常建议使用cmake
cmake_minimum_required( VERSION 2.8 ) project ( code_test ) set( CMAKE_CXX_COMPILER "g++" ) set( CMAKE_BUILD_TYPE "Debug" ) set( CMAKE_CXX_FLAGS "-std=c++11 -O0" ) include_directories( /usr/include/python3.9m ) link_directories( /usr/lib/x86_64-linux-gnu ) add_executable( run_test test.cpp ) target_link_libraries(run_test libpython3.9m.so )
Linux/Mac
首先说Linux和Mac,环境配置很简单,就是包含头文件和链接库(测试代码在后面),记得把目录替换成自己的
g++ test.cpp -I /usr/include/python3.9m -L /usr/lib/x86_64-linux-gnu -lpython3.9m
Windows
我们使用Visual Studio开发,环境配置操作和Linux/Mac 相同, 只是我们是visual studio gui操作,首先我们打开python所在的位置:
其中有libs和include两个目录,稍后我们会在VS中引用这两个目录,这里有python39.lib,我们把这个库复制一下,重命名成python39_d.lib, 一般来说需要自己编译python,会有一个python39_d.lib,这个库python39.lib的debug版本,我们这里没有自己编译代码,也不需要进python的调试,所以我们用release库替代,只链接python39.lib就可以了。(如果你有链接调试库的需求,可以官网下载源码包自行编译)
我们进入VS的项目配置,首先修改平台(X86/X64)为与Python相同的版本,比如博主的python是64位的,在VS中选择平台就必须要是X64。
接下来配置下包含目录和库链接目录:
附加依赖项中,可以选择手动添加python39.lib(调试模式则是python39_d.lib),这里因为现在python的头都会自动添加库的依赖,所以博主没有添加附加依赖项,如果我们自己在编译的时候提示库找不到,那么我们可以在附加依赖项里手动指定库的名字。
测试代码
接下来我们就可以来测试下,我们主函数是下面这样(建议阅读一下注释,对一些目录修改成自己的目录):
#include <Python.h> #include<iostream> using namespace std; int main() { Py_SetPythonHome(L"C:\\Users\\PengChao\\AppData\\Local\\Programs\\Python\\Python39"); /** 这句语句是在添加python.exe所在路径,不添加虽然编译没有问题,但是会在运行时出现 Fatal Python error: initfsencoding: unable to load the file system codec ModuleNotFoundError: No module named 'encodings' **/ Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化 if (!Py_IsInitialized()) { printf("初始化失败!"); return 0; } else { PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径 PyObject* pModule = NULL;//声明变量 PyObject* pFunc = NULL;// 声明变量 pModule = PyImport_ImportModule("hello");//这里是要调用的文件名hello.py if (pModule == NULL) { cout << "没找到该Python文件" << endl; } else { pFunc = PyObject_GetAttrString(pModule, "add");//这里是要调用的函数名 PyObject* args = Py_BuildValue("(ii)", 28, 103);//给python函数参数赋值 PyObject* pRet = PyObject_CallObject(pFunc, args);//调用函数 int res = 0; PyArg_Parse(pRet, "i", &res);//转换返回类型 cout << "res:" << res << endl;//输出结果 } Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。 } return 0; }
然后我们在C++代码制定的目录添加python文件,这里博主指定的是代码运行路径
测试python代码的内容:
def add(a,b): print ("These consequences are from Python code.") print ("a = " + str(a)) print ("b = " + str(b)) print ("ret = " + str(a+b)) return a + b
看到命令好窗口打印出结果,那么我们就运行成功了
如果是自己编译的提示缺少debug的dll (python39_d.dll),那么需要把自己编译出来的dll放到下面目录。(博主实际链接release库,所以不会有这个问题)
如果遇到其他问题,请参考其他博客(博主)
参考链接: