在 C++ 中嵌入 Python(CPython API)
Posted
技术标签:
【中文标题】在 C++ 中嵌入 Python(CPython API)【英文标题】:Embedding Python within C++ (CPython API) 【发布时间】:2016-01-26 10:50:20 【问题描述】:我正在尝试将 Python 嵌入到我的 C++ 项目 (Qt5) 中。我的项目如下所示:
python_test.pro:
QT += core
QT -= gui
TARGET = python_test
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH += C:\Tools\Python\Python35_64\include
LIBS += -LC:\Tools\Python\Python35_64\ -lpython3
main.cpp:
#include <Python.h>
#include <QCoreApplication>
int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
return a.exec();
编译时出现链接器错误,告诉我:main.cpp:-1: Error: undefined reference to `__imp_PyRun_SimpleStringFlags'
。
有趣的是可以找到Py_Initialize()
和Py_Finalize()
。我读了一些关于定义 Py_LIMITED_API
的内容,它隐藏了函数 PyRun_SimpleStringFlags。但我不明白。
如果没有这些函数在 C API 中可用,我应该如何运行 Python 脚本/文件/字符串?
设置:
Win7 Prof 64 位 Qt 5.5.1 g++.exe(Rev1,由 MSYS2 项目构建)5.3.0 Python 3.5.1 64 位(从 https://www.python.org/downloads/release)/python-351/ 预构建)【问题讨论】:
链接-lpython35
而不是-lpython3
可能会有所不同。
[offtopic] 我建议看看pythonqt
(pythonqt.sourceforge.net) 这是绑定 Qt 应用程序和 python 的一种非常强大的方法(它是 PyQt 反过来)
@bibi 我已经看过这个库,它看起来很完美。但是我在编译它/调试包含这个库的项目时遇到了问题。试图联系开发人员,但没有得到答复。所以我决定坚持使用 CPython API,因为我只需要运行脚本来转换字符串。
【参考方案1】:
我在我的电脑上测试了这个(虽然没有 Qt),-lpython35
编译成功,-lpython3
没有。
所以
LIBS += -LC:\Tools\Python\Python35_64\ -lpython35
而不是
LIBS += -LC:\Tools\Python\Python35_64\ -lpython3
【讨论】:
这成功了,谢谢! python3(python3.dll)创建定义 Py_LIMITED_API 以保持所有 python 3 版本(3.2、3.4 等)的 API 兼容性是否正确? @Burner 如果你把#define Py_LIMITED_API
放在你的源文件中#include <Python.h>
之前,然后尝试编译,你会注意到函数PyRun_SimpleString将不可用并且python3.dll
对应这个有限的 API。
感谢您的解释!我现在在将我的应用程序部署到另一台电脑时遇到了问题。应用程序启动正常,但一旦执行脚本(达到 PyRun_SimpleString),应用程序就会崩溃,并在文件中出现错误:C:\windows\system32\ucrtbase.dll。该 dll 在我正在使用的所有 PC 上都可用。我不知道该怎么做。以上是关于在 C++ 中嵌入 Python(CPython API)的主要内容,如果未能解决你的问题,请参考以下文章
为啥 CPython 3.4.3 不能导入“_socket”模块?
如何在 C++ 程序将使用的 Python 脚本中导入 cpython 模块?
_ctypes.cpython-39-x86_64-linux-gnu.so:未定义符号:使用 dlopen 加载的嵌入式 Python 中的 PyFloat_Type