为什么qt工程会抛出undefined reference to `__imp_ Py_Initialize'之类的错误?

Why qt project can throw errors like undefined reference to `__imp_ Py_Initialize' and so on?

我想在 C++ 代码中添加 python 函数。 项目是用qt写的。

在Mask.pro我有:

...
INCLUDEPATH += "D:/workplace/Python/include"
LIBS += -L"D:/workplace/Python/libs"
...

在main.cpp我有:

#pragma push_macro("slots")
#undef slots
#include <Python.h>
#pragma pop_macro("slots")
...
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;

Py_Initialize();
pName = PyUnicode_DecodeFSDefault("Morpho");

pModule = PyImport_Import(pName);
pFunc = PyObject_GetAttrString(pModule, 0);

Py_XDECREF(pFunc);
Py_DECREF(pModule);
...

编译时出错:

D:\workplace\Python\include\object.h:500: ошибка: undefined reference to `_imp___Py_Dealloc'
debug/main.o: In function `Py_DECREF':
D:/workplace/Python/include/object.h:500: undefined reference to `_imp___Py_Dealloc'
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug\..\Mask\main.cpp:99: ошибка: undefined reference to `_imp__Py_Initialize'
debug/main.o: In function `Z5qMainiPPc':
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug/../Mask/main.cpp:99: undefined reference to `_imp__Py_Initialize'
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug\..\Mask\main.cpp:100: ошибка: undefined reference to `_imp__PyUnicode_DecodeFSDefault'
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug\..\Mask\main.cpp:102: ошибка: undefined reference to `_imp__PyImport_Import'
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug\..\Mask\main.cpp:103: ошибка: undefined reference to `_imp__PyObject_GetAttrString'

我就是找不到我做错了什么或者我什至忘记了什么。


整个 .pro 文件:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    QMTIFF.cpp \
    main.cpp \
    mainwindow.cpp \
    processingBlock.cpp

HEADERS += \
    QMTIFF.h \
    mainwindow.h \
    processingBlock.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

DISTFILES += \
    Morpho.py

LIBS += -L"D:/workplace/Python/libs" -lpython310

INCLUDEPATH += "D:/workplace/Python/include"
DEPENDPATH += "D:/workplace/Python/include"

LIBS += -L"D:/Qt/Qt5.15.2/5.15.2/Src/qtimageformats/src/3rdparty/libtiff/libtiff" -ltiff

INCLUDEPATH += "D:/Qt/Qt5.15.2/5.15.2/Src/qtimageformats/src/3rdparty/libtiff/libtiff"
DEPENDPATH += "D:/Qt/Qt5.15.2/5.15.2/Src/qtimageformats/src/3rdparty/libtiff/libtiff"

所有错误和警告:

C:\Projects\Cproject\QT\Mask\Mask\QMTIFF.cpp:103: предупреждение: comparison between signed and unsigned integer expressions [-Wsign-compare]
..\Mask\QMTIFF.cpp: In constructor 'QMTIFF::QMTIFF(QString)':
..\Mask\QMTIFF.cpp:103:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     } while (n < NOfPages);
          ~~^~~~~~~~~~
C:\Projects\Cproject\QT\Mask\Mask\QMTIFF.cpp:53: предупреждение: unused parameter 'test' [-Wunused-parameter]
..\Mask\QMTIFF.cpp:53:24: warning: unused parameter 'test' [-Wunused-parameter]
 QMTIFF::QMTIFF(QString test)
                        ^~~~
C:\Projects\Cproject\QT\Mask\Mask\main.cpp:17: предупреждение: unused variable 'Num' [-Wunused-variable]
..\Mask\main.cpp: In function 'int qMain(int, char**)':
..\Mask\main.cpp:17:18: warning: unused variable 'Num' [-Wunused-variable]
     unsigned int Num = 1190;
                  ^~~
C:\Projects\Cproject\QT\Mask\Mask\main.cpp:25: предупреждение: unused variable 'from' [-Wunused-variable]
..\Mask\main.cpp:25:9: warning: unused variable 'from' [-Wunused-variable]
     int from = 1001;
         ^~~~
C:\Projects\Cproject\QT\Mask\Mask\main.cpp:26: предупреждение: unused variable 'to' [-Wunused-variable]
..\Mask\main.cpp:26:9: warning: unused variable 'to' [-Wunused-variable]
     int to  =  1190;
         ^~
C:\Projects\Cproject\QT\Mask\Mask\main.cpp:96: предупреждение: unused variable 'pArgs' [-Wunused-variable]
..\Mask\main.cpp:96:15: warning: unused variable 'pArgs' [-Wunused-variable]
     PyObject *pArgs, *pValue;
               ^~~~~
C:\Projects\Cproject\QT\Mask\Mask\main.cpp:96: предупреждение: unused variable 'pValue' [-Wunused-variable]
..\Mask\main.cpp:96:23: warning: unused variable 'pValue' [-Wunused-variable]
     PyObject *pArgs, *pValue;
                       ^~~~~~
D:\workplace\Python\include\object.h:500: ошибка: undefined reference to `_imp___Py_Dealloc'
debug/main.o: In function `Py_DECREF':
D:/workplace/Python/include/object.h:500: undefined reference to `_imp___Py_Dealloc'
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug\..\Mask\main.cpp:98: ошибка: undefined reference to `_imp__Py_Initialize'
debug/main.o: In function `Z5qMainiPPc':
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug/../Mask/main.cpp:98: undefined reference to `_imp__Py_Initialize'
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug\..\Mask\main.cpp:99: error: undefined reference to `_imp__PyUnicode_DecodeFSDefault'
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug\..\Mask\main.cpp:101: error: undefined reference to `_imp__PyImport_Import'
C:\Projects\Cproject\QT\Mask\build-Mask-Desktop-Debug\..\Mask\main.cpp:102: ошибка: undefined reference to `_imp__PyObject_GetAttrString'
:-1: error: collect2.exe: error: ld returned 1 exit status

Python(至少是官方二进制文件)用于 Win 是使用 VStudio[Python.Wiki]: WindowsCompilers)。
根据一段时间后添加的输出行 (:-1: error: collect2.exe: error: ld returned 1 exit status),它似乎是一个不同的构建工具链(看起来像来自 Nix 的端口(MinGW, MSYS2, Cygwin, ...)) 被使用。

通常建议不要混合构建工具链,因为这可能会产生错误(在构建时,或者(甚至更糟)在运行时崩溃)。检查 [SO]: How to circumvent Windows Universal CRT headers dependency on vcruntime.h (@CristiFati's answer) 以获取远程相关示例。

尝试在 .pro[ 中设置 VStudio(可能需要安装它 - Community Edition 是免费的) =63=] 文件,如下图(不要介意旧版本,这是我已经配置的):



这(原始答案)是一般性建议,不是当前失败的原因,因为库是自动包含的(通过 pyconfig.h)。

您指定了链接器应在何处搜索库,但未指定要使用的库。查看 了解有关在 Win.

上构建的更多详细信息

Pythonlib 目录中("D:/workplace/Python/libs" 在你的情况下),应该有一个名为 python${PYTHON_MAJOR}${PYTHON_MINOR}.lib 取决于您使用的 Python 版本(例如 python39.lib 对于 Python 3.9)。您需要让链接器知道它:

LIBS += -L"D:/workplace/Python/libs" -lpython39

注意:在Win上你不必单独安装Python 包 (python*, libpython*, libpython *-dev, ...) 因为它们都包含在(官方)安装程序中。