为何调用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目录下即可。
关注
笔者 - jxd