目录
功能说明
动态库制作
打包软件发布
运行效果
功能说明
完成一个表达式计算的功能,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动态库



