C++调用Python总结

C++调用Python用法总结

项目中需要用到C++调用Pyhton文件中的函数,因此总结了一下常用的使用的方法。

环境

Pyhton2.7
在C++程序中需要应用Python的头文件,在VisualStudio环境中调试的时候使用的是Debug模式,而Python的配置文件pyconfig.h(C:\Python27\include\pyconfig.h)文件中声明了当在Debug模式下调试时,需要引用python27_d.lib的库文件,但是在安装Python的时候并无此文件。

/* For an MSVC DLL, we can nominate the .lib files used by extensions */
#ifdef MS_COREDLL
#	ifndef Py_BUILD_CORE /* not building the core - must be an ext */
#		if defined(_MSC_VER)
			/* So MSVC users need not specify the .lib file in
			their Makefile (other compilers are generally
			taken care of by distutils.) */
#			ifdef _DEBUG
#				pragma comment(lib,"python27_d.lib")/*Debug模式下应用python27_d.lib文件*/
#			else
#				pragma comment(lib,"python27.lib")
#			endif /* _DEBUG */
#		endif /* _MSC_VER */
#	endif /* Py_BUILD_CORE */
#endif /* MS_COREDLL */

为了解决在Debug模式下调试报错的问题,需在C++程序头部进行如下引用:

#ifdef _DEBUG
#undef _DEBUG
#include "Python.h"
#define _DEBUG
#else
#include "Python.h"
#endif

C++调用Python用法示例

1)执行简单Python语句

int main()
{
	Py_Initialize();
	PyRun_SimpleString("print('Hello Python!')\n");
	Py_Finalize();
	return 0
}

2)调用python文件中的函数(无参数)
Python代码:Test001.py

def Hello():
    print("Hello Python hello python ")

C++代码

void mian()
{
	Py_Initialize();//调用Py_Initialize()进行初始化
	
	if (!Py_IsInitialized())
	{
		printf("初始化失败!");
	}
	PyRun_SimpleString("import os,sys");
	PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径
	
	PyObject * pModule = NULL;
	PyObject * pFunc = NULL;
	pModule = PyImport_ImportModule("Test001");//调用的Python文件名,将Test001.py文件放在
	pFunc = PyObject_GetAttrString(pModule, "Hello");//调用的函数名
	PyEval_CallObject(pFunc, NULL);//调用函数,NULL表示参数为空
	//PyObject_CallObject(pFunc, NULL);
	
	if (pFunc)
		Py_DECREF(pFunc);//此步为对Python传过来的对象引用次数逐步降低	
	if (pModule)
		Py_DECREF(pModule);
	
	Py_Finalize();//调用Py_Finalize,和Py_Initialize相对应的.
}

3)调用Python文件中的函数,输入多个参数并获取单个返回值
Python代码:Test001.py

def Hello():
    print("Hello Python hello python ")
 
def Add(a,b):
    return a+b

C++代码:

void main()
{
	Py_Initialize();
	if (!Py_IsInitialized())
	{
		printf("初始化失败!");
	}
	PyRun_SimpleString("import os,sys");
	PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径

	int res;
	PyObject *pModule = NULL;
	PyObject *pFunc = NULL;
	PyObject *pArgs = NULL;
	PyObject *pRet = NULL;

	/* import */
	pModule = PyImport_ImportModule("Test001");//调用的Python文件名
	if (!pModule)
	{
		printf("import python failed!!\n");
	}

	/* Test001.Add */	
	pFunc = PyObject_GetAttrString(pModule, "Add");
	if (!pFunc)
	{
		printf("get python function failed!!!\n");
	}

	/* build args */
	pArgs = PyTuple_New(2);
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", a));
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", b));

	/* call */
	pRet = PyEval_CallObject(pFunc, pArgs);
	PyArg_Parse(pRet, "i", &res);//i表示转换成int型变量
	return res;

	if(pRet)
		Py_DECREF(pRet);
	if (pArgs)
		Py_DECREF(pArgs);
	if (pFunc)
		Py_DECREF(pFunc);
	if (pModule)
		Py_DECREF(pModule);
	
	Py_Finalize();
}

4)调用Python文件中的函数,输入多个参数并获取单个返回值
Python代码:Test001.py

def Hello():
    print("Hello Python hello python ")
 
def Add(a,b):
    return a+b

def AddMult(a,b):
	return a+b,a*b

C++代码:

void main()
{
	Py_Initialize();
	PyRun_SimpleString("import os,sys");
	PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径

	PyObject *pModule = NULL;
	PyObject *pFunc = NULL;
	PyObject *pArgs = NULL;
	PyObject *pRet = NULL;

	/* import */
	pModule = PyImport_ImportModule("Test001");
	if (!pModule)
	{
		printf("import python failed!!\n");
	}
	
	//Test001.AddMult
	pFunc = PyObject_GetAttrString(pModule, "AddMult");
	if (!pFunc)
	{
		printf("get python function failed!!!\n");
	}
	
	/* build args */
	//pArgs = Py_BuildValue("ii", a, b);
	pArgs = PyTuple_New(2);
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", a));
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", b));

	/* call */
	//pRet = PyObject_CallObject(pFunc, pArgs);
	pRet = PyEval_CallObject(pFunc, pArgs);
	int c = 0;
	int d = 0;
	PyArg_ParseTuple(pRet, "ii", &c, &d);
	std::cout<<"sum:"<< c <<std::endl;
	std::cout<<"mult:"<< d <<std::endl;

	if (pRet)
		Py_DECREF(pRet);
	if (pArgs)
		Py_DECREF(pArgs);
	if (pFunc)
		Py_DECREF(pFunc);
	if (pModule)
		Py_DECREF(pModule);
		
	//只有最后一步才调用Py_Finalize(),此时python全局变量一直保存着
	Py_Finalize();
}

5)执行Python文件,并传入系统参数
Python代码:

import sys,os
print(sys.argv[0])

C++代码:

void main()
{
	//第一步:初始化Python
	//在调用Python的提供的给C的API之前,通过执行初始化
	//来添加Python的内建模块、__main__、sys等
	Py_Initialize();

	//检查初始化是否完成
	if (!Py_IsInitialized())
	{
		printf("初始化失败!");
	}

	//第二步:导入sys模块
	PyRun_SimpleString("import os,sys");
	PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径

	//第三步:导入执行脚本时的命令行参数,如:./sample.py arg1 arg2
	int argc = 1;
	char* argv[1];
	argv[0] = (char*)"This is a test string";
	PySys_SetArgv(argc, argv);
	//第四步:执行调用脚本文件命令,注意文件的路径
	PyObject* PyFileObject = PyFile_FromString((char*)"Test002.py", (char*)"rb");
	PyRun_SimpleFile(PyFile_AsFile(PyFileObject), (char*)"Test002.py");

	//第五步:关闭Python解释器
	Py_Finalize();
}

6)将Python文件以字符串的形式调用
C++代码:

void main()
{
Py_Initialize();

	//检查初始化是否完成
	if (!Py_IsInitialized())
	{
		printf("初始化失败!");
	}

	//第二步:导入sys模块
	PyRun_SimpleString("import os,sys");
	PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径

	//第三步:导入执行脚本时的命令行参数,如:./sample.py arg1 arg2

	int argc = 1;
	char* argv[1];
	argv[0] = (char*)"BW.txt";
	PySys_SetArgv(argc, argv);

	//将下面的python语句转化为16进制形式
	//
	//import sys
	//
	//	def main() :
	//	print(sys.argv[0])
	//
	//
	//	if __name__ == '__main__' :
	//		main()
	unsigned char arg2[] = {
		0x0D, 0x0A, 0x69, 0x6D, 0x70, 0x6F, 0x72, 0x74, 0x20, 0x73, 0x79, 0x73, 0x0D, 0x0A, 0x0D, 0x0A,
		0x64, 0x65, 0x66, 0x20, 0x6D, 0x61, 0x69, 0x6E, 0x28, 0x29, 0x3A, 0x0D, 0x0A, 0x09, 0x70, 0x72,
		0x69, 0x6E, 0x74, 0x28, 0x73, 0x79, 0x73, 0x2E, 0x61, 0x72, 0x67, 0x76, 0x5B, 0x30, 0x5D, 0x29,
		0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x69, 0x66, 0x20, 0x5F, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x5F,
		0x5F, 0x3D, 0x3D, 0x27, 0x5F, 0x5F, 0x6D, 0x61, 0x69, 0x6E, 0x5F, 0x5F, 0x27, 0x3A, 0x0D, 0x0A,
		0x09, 0x6D, 0x61, 0x69, 0x6E, 0x28, 0x29, 0x00
	};

	Py_Finalize();
}

7)定义Python 函数,生成PythonModule,并调用PythonModule
C++代码:

void main()
{
	Py_Initialize();
	// compile our function
	std::stringstream buf;
	buf << "def add( n1 , n2 ) :" << std::endl
		<< "    return n1+n2" << std::endl;
	PyObject* pCompiledFn = Py_CompileString(buf.str().c_str(), "", Py_file_input);//将Python 指令进行编译
	assert(pCompiledFn != NULL);

	// create a module      
	PyObject* pModule = PyImport_ExecCodeModule((char*)"test", pCompiledFn);//将编译后的Python指令生成为Python Module
	assert(pModule != NULL);

	// locate the "add" function (it's an attribute of the module)
	PyObject* pAddFn = PyObject_GetAttrString(pModule, "add");//调用Python Module中的add函数
	assert(pAddFn != NULL);

	int a = 1;
	int b = 2;
	PyObject* pArgs = PyTuple_New(2);//创建参数元组
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", a));
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", b));

	//PyObject* pRet = PyObject_CallObject(pAddFn, pArgs);//调用Python Module中add函数

	int res;
	PyArg_Parse(pRet, "i", &res);//将返回的结果转化为int类型
	std::cout << res << std::endl;
	
	// clean up
	Py_DecRef(pAddFn);
	Py_DecRef(pModule);
	Py_DecRef(pCompiledFn);
	Py_Finalize();
}

8)调用Pyhton中的类、实例、函数,参考下面的链接
[C++/Python] 如何在C++中使用一个Python类?

参考文献
C++调用python的那些坑(详细教程步骤)
Calling Python code from your program
C++调用Python浅析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值