Python二次开发顾名思义就是将Python作为脚本语言对系统进行定制修改,功能扩展,从而让系统变得更全面,便于企业的长远发展。市面上系统支持用Python进行二次开发不少,例如:百数搭建的系统就支持用Python进行二次开发,有需要的小伙伴们可以了解一下。
C++调用Python浅析
常见错误
LNK2019 无法解析的外部符号 __imp__Py_RefTotal,函数 _Py_DECREF 中引用了该符号
LNK2019 无法解析的外部符号 __imp__Py_NegativeRefcount,函数 _Py_DECREF 中引用了该符号
解决方法:
打开Python安装目录下的object.h文件,注释该文件第57行(Python版本不同,行数不同):#define Py_REF_DEBUG
保存时如果提示无权限,文件属性->安全->编辑->添加Everyone->完全控制
示例(vs2019,python3.8)
-
第一步需要安装Python
-
VS解决方案设置包含目录等
- C/C++->附加包含目录:添加Python安装目录下的include目录
- 链接器->附加库目录:添加Python安装目录下的libs目录
- 包含目录附加库目录设置各种问题解决方案
注意:如果VS解决方案为DEBUG模式,需要将libs目录下的Python38.lib复制一份并重命名为Python38_d.lib
-
C++代码:
#include <iostream>
#include <Python.h>
int main()
{
Py_Initialize(); //初始化python环境
if (!Py_IsInitialized)
{
std::cout << "Python解释器初始化失败" << std::endl;
return 0;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject* pModule = PyImport_ImportModule("mytest"); //导入模块
if (!pModule)
{
std::cout << "Python get module failed." << std::endl;
return 0;
}
std::cout << "Python get module succeed." << std::endl;
PyObject* pFunc = nullptr;
pFunc = PyObject_GetAttrString(pModule, "Hello"); //Hello是Python文件里的函数
PyEval_CallObject(pFunc, NULL); //Python3.9不可用
PyObject* pv = PyObject_GetAttrString(pModule, "_add");
if (!pv || !PyCallable_Check(pv))
{
std::cout << "Can't find function(_add)" << std::endl;
}
std::cout << "Get function succeed." << std::endl;
//初始化要传入的参数,args配置成传入两个参数的模式
PyObject* args = PyTuple_New(2);
//将Long型数据转换成Python可接受的数据
PyObject* arg1 = PyLong_FromLong(4);
PyObject* arg2 = PyLong_FromLong(2);
//将arg1配置为arg带入的第一个参数
PyTuple_SetItem(args, 0, arg1);
//将arg2配置为arg带入的第二个参数
PyTuple_SetItem(args, 1, arg2);
//传入参数调用函数,并获取返回值
PyObject* pRet = PyObject_CallObject(pv, args);
if (pRet)
{
//将返回值转换成Long型
long result = PyLong_AsLong(pRet);
std::cout << "result:" << result << std::endl;
}
Py_Finalize();
system("pause");
return 0;
}
- Python代码(文件名为mytest.py):
def Hello():
print("Hello World")
def _add(x,y):
print(x,"add",y)
return x + y