1 前言
python 是 C 写的,库也是 C 写的,不但 python 可以调用 C 写的库,C也能调用为 python 写的库,甚至调用 python 语句执行。
嵌入为应用程序提供了用Python而不是C或c++实现应用程序的某些功能的能力。这可以用于许多目的;
一个例子是允许用户通过用Python编写一些脚本来根据自己的需要定制应用程序。
如果一些功能可以更容易地用Python编写,您也可以自己使用它。
嵌入Python类似于扩展它,但并不完全如此。所不同的是,当你扩展Python应用程序的主程序仍然是Python解释器,
而如果你嵌入Python,主程序可能与Python——相反,应用程序的某些部分偶尔会调用Python解释器来运行一些Python代码。
2 案例
直接给出一个例子,使用 Qt 调用 python。在 qt 中直接创建 Qt console Application 项目,以下所有内容都是终端应用程序项目。
#define PY_SSIZE_T_CLEAN
#include <QCoreApplication>
#include <Python.h>
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
wchar_t *program = Py_DecodeLocale(argv[0], nullptr);
if (program == nullptr) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString ("from time import time,ctime\n"
"print('今日是:', ctime(time()))\n"
"print('大家好!')\n"
);
if (Py_FinalizeEx() < 0) {
exit(120);
}
PyMem_RawFree(program);
return a.exec();
}
3.解释
如果你嵌入Python,你就提供了你自己的主程序。这个主程序要做的一件事就是初始化Python解释器。
1) 至少,您必须调用函数Py_Initialize()。有一些可选调用将命令行参数传递给Python。然后,您可以从应用程序的任何部分调用解释器。
2) 调用解释器有几种不同的方法:可以将包含Python语句的字符串传递给PyRun_SimpleString(),
3) 也可以将stdio文件指针和文件名(仅用于在错误消息中标识)传递给PyRun_SimpleFile()。
4) 您还可以调用低层操作来构造和使用Python对象。
4.运行结果
相当于运行 python语句
from time import time,ctime
print(”今日是:“, ctime(time())
print('”大家好!")
5 创建说明
Qtz 中要调用 python 必须明白 python 的 include 和 lib所在的目录
5.1 查找 python 的目录
一个命令:python3.7-config --cflags
另外一个命令:python3.7-config --ldflags
分别显示 python 的头文件和库文件所在,在 pro 文件中定义
# $ python3.7-config --cflags
# -I/anaconda3/include/python3.7m -I/anaconda3/include/python3.7m -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/anaconda3/include -arch x86_64 -I/anaconda3/include -arch x86_64
# $ python3.7-config --ldflags
# -L/anaconda3/lib/python3.7/config-3.7m-darwin -lpython3.7m -ldl -framework CoreFoundation -Wl,-stack_size,1000000 -framework CoreFoundation
INCLUDEPATH += /anaconda3/include/python3.7m
LIBS += -L/anaconda3/lib/python3.7/config-3.7m-darwin -lpython3.7m -ldl
CONFIG += no_keywords
# /anaconda3/include/python3.7m/object.h:450: error: expected member name or ';' after declaration specifiers
# PyType_Slot *slots; /* terminated by slot==0. */
# ~~~~~~~~~~~ ^
5.2 在 pro 文件中添加
CONFIG += no_keywords
就是为了避免python 中的 object.h 文件中有 Qt 的保留字 slots,使用配置忽视它。