C++调用python(一)环境配置

使用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。

接下来配置下包含目录和库链接目录:

f画u ju jiu jiau家

附加依赖项中,可以选择手动添加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库,所以不会有这个问题)

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

参考链接:

https://blog.csdn.net/S2280098682/article/details/109125417

https://blog.csdn.net/omg_orange/article/details/100106926

发表评论