C++调用python2文件(Pyc)

本文详述了如何在C++中调用Python2代码,包括生成.pyc文件、配置C++工程、处理库依赖及实现函数调用的具体步骤。通过一个简单的demo,展示了从环境搭建到代码实现的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.youkuaiyun.com/stq054188/article/details/82012901
【2】https://www.cnblogs.com/apexchu/p/5015961.html
【3】https://blog.youkuaiyun.com/qq_32716885/article/details/80651433

C++环境中调用Python,通常使用C++的Boost.Python库或者Pybind11等第三方库作为接口,让C++能访问Python的功能,包括Python模块。如果你需要调用Python中的加密功能,特别是已经编译为`pyc`(Pickled Python文件的模块,这些文件实际上是经过序列化处理的二进制形式,可以直接被Python加载执行。 当你在Python中对某个模块进行`import`并将其编译为`pyc`文件后,这个过程主要是为了提升加载速度,因为每次导入都重新解析模块源码可能会较慢。在C++中要使用这个已编译的模块,你需要确保以下几个步骤: 1. **包含头文件**:使用对应的库(如`boost/python.hpp`或`pybind11/pybind11.h`)来引用Python API。 2. **动态链接**:由于`pyc`文件是在Python运行时使用的,所以你需要链接到Python的动态库(通常是`libpython`),而不是静态链接。 3. **加载模块**:使用`PyImport_ImportModule()`函数从C++中动态加载`pyc`文件所对应的模块。 ```cpp #include <boost/python.hpp> // 假设你的模块名是"my_encryption_module" namespace bp = boost::python; int main() { try { // 使用Py_Initialize()初始化Python环境 Py_Initialize(); // 加载模块 object module = bp::handle<>(PyImport_ImportModule("path_to_your_pyc_file")); // 访问模块中的加密函数,假设名称是"encrypt" function encrypt_func = module.attr("encrypt"); // 执行加密 std::string encrypted_data = encrypt_func("plaintext"); // 清理Python环境 Py_Finalize(); } catch (std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } return 0; } ``` 请注意,上述代码示例基于Boost.Python,如果你使用的是Pybind11,则接口会有不同。此外,对于实际应用,可能还需要处理异常、内存管理和错误处理等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值