zoukankan      html  css  js  c++  java
  • C++程序嵌入Python解释器二次开发

    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解决方案设置包含目录等

      1. C/C++->附加包含目录:添加Python安装目录下的include目录
      2. 链接器->附加库目录:添加Python安装目录下的libs目录
      3. 包含目录附加库目录设置各种问题解决方案
        注意:如果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
    

    结果:

    输出

  • 相关阅读:
    Linux文件及目录查找
    英语单词independent
    英语单词omitting
    英语单词deploy
    英语单词debug
    线程
    进程
    操作系统历史
    分布式爬虫
    爬虫基础
  • 原文地址:https://www.cnblogs.com/mmmmmmmmm/p/14586030.html
Copyright © 2011-2022 走看看