C++调用python2文件(Pyc)

C++调用python2文件(Pyc)

最近做一个小的程序里面涉及用C++调用python2,其中有许多很坑的地方需要在这里提醒大家,避免的大家在走同样的弯路。这里以一个简单的demo做为例子
本文用的python环境是python 2.7.12

1编写TestAdd.py文件

代码如下:

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

2.定位到Test.py的其所在目录,运行cmd生成TestAdd.pyc文件

在cmd中执行下面的命令就可以

python -m py_compile TestAdd.py

执行完成后在当前目录会生成TestAdd.pyc文件

3新建C++工程

本人用的是原生python而非Anaconda下的python,需要将python27下的include文件夹和libs文件夹拷贝到项目中

在这里插入图片描述
在这里插入图片描述
并且之前的py文件和pyc文件也要拷贝到项目中放在与Debug同级目录即可

4配置相关属性

右击项目点击属性–>链接器–>常规,配置附件库目录,这里加入是libs相对于生成exe的路径
在这里插入图片描述
这里需要注意的一点,将libs中的python27.lib重命名为python27_d.lib(这个的原因是include目录下的pyconfig.h里面的代码再debug下调用的是python27_d.lib)。否则会出现以下错误:

LINK : fatal error LNK1104: 无法打开文件“python27_d.lib”

在属性–>链接器–>输入中的附加依赖项,添加python27_d.lib
在这里插入图片描述

6编写pythontest.cpp文件

代码如下:

#include <iostream>
#include "include/Python.h"
using namespace std;

void Hello()
{
	Py_Initialize();
	PyObject * pModule = NULL;
	PyObject * pFunc = NULL;
	pModule = PyImport_ImportModule("TestAdd");
	pFunc = PyObject_GetAttrString(pModule, "Hello");
	PyEval_CallObject(pFunc, NULL);
	Py_Finalize();
}
void Add(int a1,int a2) {
	Py_Initialize();
	PyObject* pModule = NULL;
	PyObject* pFunc = NULL;
	pModule = PyImport_ImportModule("TestAdd");
	pFunc = PyObject_GetAttrString(pModule, "Add");
	//创建参数
	PyObject* pArgs = PyTuple_New(2);
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", a1));
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", a2));
	//返回值
	PyObject* pReturn = NULL;
	pReturn = PyEval_CallObject(pFunc, pArgs);
	//将返回值转换为int类型
	int result;
	PyArg_Parse(pReturn, "i", &result);
	cout << "a1+a2=" << result << endl;
	Py_Finalize();

}

int main() {
	cout << "调用TestAdd.py中的Hello函数..." << endl;
	Hello();
	cout << "调用TestAdd.py中的Add函数..." << endl;
	Add(6, 8);
	getchar();
	return 0;

}

执行结果
在这里插入图片描述
关于代码部分,首先是添加python的声明

#include “Python.h”

然后是对python接口的初始化

Py_Initialize();

初始化变量,这里的变量主要是调用的py文件,调用的方法

PyObject * pModule = NULL;
PyObject * pFunc=NULL;

调用py文件名以及调用方法

pModule = PyImport_ImportModule("TestAdd");
pFunc = PyObject_GetAttrString(pModule, "Add");

创建参数

PyObject* pArgs = PyTuple_New(2);//函数调用的参数传递均是以元组的形式打包的,2表示参数个数
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", a1));//传入第一个参数
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", a2));//传入第二个参数

使用C++调用python接口

PyObject* pReturn = NULL;
pReturn = PyEval_CallObject(pFunc, pArgs);

用C++变量接收返回值

int result;
PyArg_Parse(pReturn, "i", &result);

结束调用python接口

Py_Finalize();

关于C++与python之间的数据转换的代码
在这里插入图片描述
这里对应的就是上面代码中Py_BuildValue和PyArg_Parse的参数

参考文章

【1】https://blog.csdn.net/stq054188/article/details/82012901
【2】https://www.cnblogs.com/apexchu/p/5015961.html
【3】https://blog.csdn.net/qq_32716885/article/details/80651433

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值