使用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库,所以不会有这个问题)

如果遇到其他问题,请参考其他博客(博主)
参考链接: