C++调用Python3函数与类对象

为何调用Python

     基于Python庞大且不断发展的社区,对开源库的巨大支持,以及它支持各种应用程序,如Web应用程序编程,数据科学,数据可视化和通用自动化。如果您尝试在这些领域使用C/C++,这简直是噩梦,非常复杂。 两者若相互调用,C++被Python补足缺陷、Python被C++补足效率等方面,那么嘻嘻。。

安装Python

     这里C++环境为Vs,并默认已安装。
     进入Python官网,本章为Python版本3.7.4。

创建C艹工程并配置
  • 创建C艹工程
         新建项目Cpp2Py并创建main.cpp
    在这里插入图片描述

  • 配置Python
         1、将Python安装目录下include和libs文件拷贝到C艹工程下。
    在这里插入图片描述
         2、将拷贝出来的lib文件中Python37.lib拷贝一份改名为"python37_d.lib"。因为在配置时debug加入"python37_d.lib"、release加入"python37.lib"

         3、配置工程 (本章仅配置release版本)
              ①项目 - 配置属性 - C/C++ - 常规 - 附加包含目录,填include相对路径
              ②项目 - 配置属性 - 链接器 - 常规 - 附加库目录,填lib相对路径
              ③项目 - 配置属性 - 链接器 - 输入 - 附加依赖项,填python37.lib

调用Python

     py.py文件

# 函数
def Hello():
	print('hello,world!')
	
def SayHello(name):
	print('hello,',name,'!')
	
def GetHello(name):
	return 'hello,'+name+'!'
	
def AddValue(x,y):
	return x + y
	
	
# 类
class Person():

	__age = 18
	__food = 'whatever'

	def WhatEat(self):
		print('no mind!')
		
	def EatThis(self,foodName):
		self.__food = foodName
		
	def GetEat(self):
		return self.__food;
		
	def GetAge(self):
		return self.__age

     相关函数
          Python初始化 —— Py_Initialize()
          引库 —— PyRun_SimpleString(“import sys”)
          引路径 —— PyRun_SimpleString(“sys.path.append(’./’)”);
          引py文件 —— PyImport_ImportModule(“py”)
          索引函数名 —— PyObject_GetAttrString()
          调用 —— PyObject_CallObject()
          释放对象资源 —— Py_DECREF()
          释放资源 —— Py_Finalize()

     调用函数代码

// 使用python之前,要调用Py_Initialize();这个函数进行初始化
	Py_Initialize();
	if (!Py_IsInitialized())
	{
		printf("初始化失败!");
		PAUSE;
		return -1;
	}

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

	PyObject * pModule = nullptr;								//声明变量
	pModule = PyImport_ImportModule("py");						//这里是要调用的文件名py.py,(注意把test.py改名,python自带测试模组且优先级高于用户的)
	if (pModule == nullptr)
	{
		cout << "没找到" << endl;
		PAUSE;
		return -2;
	}

	/* 开始调用Python函数***********************************************************************/

	// 调用Hello函数
	PyObject *HelloFunc = PyObject_GetAttrString(pModule, "Hello");				//这里是要调用的函数名
	PyObject *HelloArgs = nullptr;
	PyObject *HelloRet = PyObject_CallObject(HelloFunc, HelloArgs);				//调用函数
	PYOBJECT_DELETE(HelloFunc);
	PYOBJECT_DELETE(HelloArgs);
	PYOBJECT_DELETE(HelloRet);

	// 调用SayHello函数
	PyObject *SayHelloFunc = PyObject_GetAttrString(pModule, "SayHello");		//这里是要调用的函数名
	PyObject *SayHelloArgs = Py_BuildValue("(s)", "zhangsan");					//给python函数参数赋值
	PyObject *SayHelloRet = PyObject_CallObject(SayHelloFunc, SayHelloArgs);	//调用函数
	PYOBJECT_DELETE(SayHelloFunc);
	PYOBJECT_DELETE(SayHelloArgs);
	PYOBJECT_DELETE(SayHelloRet);

	// 调用GetHello函数
	PyObject *GetHelloFunc = PyObject_GetAttrString(pModule, "GetHello");		//这里是要调用的函数名
	PyObject *GetHelloArgs = Py_BuildValue("(s)", "wl");						//给python函数参数赋值
	PyObject *GetHelloRet = PyObject_CallObject(GetHelloFunc, GetHelloArgs);	//调用函数
	char *GetHelloReturn = nullptr;
	PyArg_Parse(GetHelloRet, "s", &GetHelloReturn);								//转换返回类型
	cout << "GetHello:" << GetHelloReturn << endl;
	GetHelloReturn = nullptr;
	PYOBJECT_DELETE(GetHelloFunc);
	PYOBJECT_DELETE(GetHelloArgs);
	PYOBJECT_DELETE(GetHelloRet);

	// 调用AddValue函数
	PyObject *AddValueFunc = PyObject_GetAttrString(pModule, "AddValue");		//这里是要调用的函数名
	PyObject *AddValueArgs = Py_BuildValue("(ii)", 50, 100);					//给python函数参数赋值
	PyObject *AddValueRet = PyObject_CallObject(AddValueFunc, AddValueArgs);	//调用函数
	int AddValueReturn = 0;
	PyArg_Parse(AddValueRet, "i", &AddValueReturn);								//转换返回类型
	cout << "AddValue:" << AddValueReturn << endl << endl;
	PYOBJECT_DELETE(AddValueFunc);
	PYOBJECT_DELETE(AddValueArgs);
	PYOBJECT_DELETE(AddValueRet);

	/* 开始调用Python函数**********************************************************************结束*/
	// 清理
	PYOBJECT_DELETE(pModule);
	
	Py_Finalize();

     调用类代码

// 使用python之前,要调用Py_Initialize();这个函数进行初始化
	Py_Initialize();
	if (!Py_IsInitialized())
	{
		printf("初始化失败!");
		PAUSE;
		return -1;
	}

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

	PyObject * pModule = nullptr;								//声明变量
	pModule = PyImport_ImportModule("py");						//这里是要调用的文件名py.py,(注意把test.py改名,python自带测试模组且优先级高于用户的)
	if (pModule == nullptr)
	{
		cout << "没找到" << endl;
		PAUSE;
		return -2;
	}
	
/* 开始调用Python类***********************************************************************/
	// 模块的字典列表
	PyObject* pDict = PyModule_GetDict(pModule);
	if (!pDict)
	{
		cout << "Cant find dictionary." << endl;
		PAUSE;
		return -1;
	}

	// 获取Person类
	PyObject* pClasspPerson = PyDict_GetItemString(pDict, "Person");
	if (!pClasspPerson)
	{
		cout << "Cant find Person class." << endl;
		PAUSE;
		return -1;
	}

	// 构造Person的实例
	PyObject* pInstancePerson = PyObject_CallObject(pClasspPerson, nullptr);
	if (!pInstancePerson)
	{
		printf("Cant find calc instance./n");
		PAUSE;
		return -1;
	}

	// 调用类方法 - WhatEat
	PyObject *WhatEatreturn = PyObject_CallMethod(pInstancePerson, "WhatEat", "", "");
	if (!WhatEatreturn)
	{
		printf("不能找到 WhatEat 方法!");
		PAUSE;
		return -1;
	}
	PYOBJECT_DELETE(WhatEatreturn);

	// 调用类方法 - EatThis
	PyObject *EatThisReturn = PyObject_CallMethod(pInstancePerson, "EatThis", "(s)", "rice");
	if (!EatThisReturn)
	{
		printf("不能找到 EatThis 方法!");
		PAUSE;
		return -1;
	}
	PYOBJECT_DELETE(EatThisReturn);

	// 调用类方法 - GetEat
	PyObject *GetEatReturn = PyObject_CallMethod(pInstancePerson, "GetEat", "", "");
	if (!GetEatReturn)
	{
		printf("不能找到 GetEatReturn 方法!");
		PAUSE;
		return -1;
	}
	char *GetEatBuf = nullptr;
	PyArg_Parse(GetEatReturn, "s", &GetEatBuf);								//转换返回类型
	std::cout << "Person GetEat: " << GetEatBuf << endl;
	GetEatBuf = nullptr;
	PYOBJECT_DELETE(GetEatReturn);

	// 调用类方法 - GetAge
	PyObject *GetAgeReturn = PyObject_CallMethod(pInstancePerson, "GetAge", "", "");
	if (!GetAgeReturn)
	{
		printf("不能找到 GetAgeReturn 方法!");
		PAUSE;
		return -1;
	}
	int GetAgeValue;
	PyArg_Parse(GetAgeReturn, "i", &GetAgeValue);								//转换返回类型
	std::cout << "Person GetAge: " << GetAgeValue << endl;
	PYOBJECT_DELETE(GetAgeReturn);

	// 清理
	PYOBJECT_DELETE(pInstancePerson);
	PYOBJECT_DELETE(pClasspPerson);
	PYOBJECT_DELETE(pDict);

	/* 开始调用Python类**********************************************************************结束*/

	// 清理
	PYOBJECT_DELETE(pModule);

	Py_Finalize();												//调用Py_Finalize,这个根Py_Initialize相对应的。

结果、打包

     结果在这里插入图片描述

     打包
        方式1:将被调用的py文件拷贝到exe,从而使得程序可继续执行。

        方式2:将exe目录下的__pycache__文件夹内的pyc文件拷贝到exe目录下即可。

源码下载

源码下载

关注

微信公众号搜索"Qt_io_"或"Qt开发者中心"了解更多关于Qt、C++开发知识.。

笔者 - jxd

发布了43 篇原创文章 · 获赞 0 · 访问量 3004

猜你喜欢

转载自blog.csdn.net/automoblie0/article/details/102461477