C++调用Python完成“表达式计算”功能并打包发布

C++调用Python完成“表达式计算”功能并打包发布,第1张

C++调用Python完成“表达式计算”功能并打包发布

目录

功能说明

动态库制作

打包软件发布

运行效果


功能说明

完成一个表达式计算的功能,C++实现此功能比较麻烦,直接使用python中的eval函数。本文使用c++与python交互的方式完成此功能,并在qt中制作动态库的形式供界面调用。

Python 提供了一套 C API库,使得开发者能很方便地从C/ C++ 程序中调用 Python 模块。

具体的文档参考官方指南 1. Embedding Python in Another Application — Python 3.7.12 documentation

开发环境

python3.7 miniconda安装的

QT5.10.1

动态库制作

目录结构

pro文件

动态库模板,设置python的路径

#-------------------------------------------------
#
# Project created by QtCreator 2021-11-18T16:10:13
#
#-------------------------------------------------

QT       -= gui

TARGET = CZPyInterface
TEMPLATE = lib

DESTDIR = ../../bin

DEFINES += PYINTERFACE_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += 
        PyInterface.cpp

HEADERS += 
        PyInterface.h 
        pyinterface_global.h 

unix {
    target.path = /usr/lib
    INSTALLS += target
}

# python
LIBS += -L$$PWD/../../../3rdparty/python-3.7.10/libs -lpython37
INCLUDEPATH += $$PWD/../../../3rdparty/python-3.7.10/include
DEPENDPATH += $$PWD/../../../3rdparty/python-3.7.10/include

DISTFILES += 
    python_eval.py

 

Python封装eval函数

python_eval.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from math import *
def eval_function(a):
    print("input:{}".format(a))
    try:
        val = eval(a)
        return float(val)
    except Exception as e:
        print("err:{}".format(str(e)))
        return 0

C++封装eval函数

PyInterface.h

#ifndef PYINTERFACE_H
#define PYINTERFACE_H

#include "pyinterface_global.h"

class PYINTERFACESHARED_EXPORT PyInterface
{

public:
    PyInterface();
    ~PyInterface();
    static double evalcpp(const QString &expr);
};

#endif // PYINTERFACE_H

PyInterface.cpp

#include "PyInterface.h"
#include 
#include 
#include 
#include 

PyInterface::PyInterface()
{

}

PyInterface::~PyInterface()
{

}

double PyInterface::evalcpp(const QString &expr)
{
    double d = 0;
//    Py_SetPythonHome(L"./python");
    Py_Initialize();
    if (Py_IsInitialized())
    {
        
        PyRun_SimpleString("import sys");
        PyRun_SimpleString("sys.path.append('./')");

        
        PyObject *pModule, *pFunc;
        pModule = Pyimport_importModule("python_eval");
        if(pModule)
        {
            
            pFunc = PyObject_GetAttrString(pModule, "eval_function");
            
            PyObject *pArgs = PyTuple_New(1);
            PyTuple_SetItem(pArgs, 0, PyUnicode_FromString(expr.toStdString().c_str()));
            
            PyObject *pReturn = Pyeval_CallObject(pFunc, pArgs);
            PyArg_Parse(pReturn, "d", &d);
            qDebug()  << "PyArg_Parse:" << d;
        }
        else
        {
            qDebug() << "Pyimport_importModule false";
        }
    }
    else
    {
        qDebug() << "Py_IsInitialized false";
    }
    Py_Finalize();
    return d;
}

主程序调用CZPyInterface.dll库

double result = PyInterface::evalcpp(new_expression);

打包软件发布

裁剪python解释器

从python安装路径中拷贝DLLs 和Lib文件夹下所有内容到一个文件夹中,然后压缩并命名为python37.zip,大概13MB左右

最终运行目录中有以下文件

python_eval.py 自己写的py源码

python37.dll python安装路径查找

python37.zip 解释器

CZPyInterface.dll 封装的 动态库

app.exe qt界面程序

其他qt动态库

运行效果

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5679733.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存