链接错误:未定义的引用

Linking error: undefined reference

本文关键字:引用 未定义 错误 链接      更新时间:2023-10-16

我的编译器将此未定义的引用报告给openWallet(..)函数。 如您所见,我已经链接了响应库-L/usr/lib -lkdeui -kdecore -lkparts

错误:

password.cpp:(.text+0x29): undefined reference to `KWallet::Wallet::openWallet(QString const&, unsigned long long, KWallet::Wallet::OpenType)'

编译命令:

g++ -Wl,-

O1 -Wl,-rpath-link,/usr/lib/x86_64-linux-gnu -o password_client "ALL *.o FILES" -L/usr/lib -lkdecore -lkdeui -lkparts -lglib-2.0 -L/usr/X11R6/lib64 -L/usr/lib/x86_64-linux-gnu -lGL -lpthread

QtCreator报告了相同的错误。 .pro文件包含

LIBS += -lkdecore 
        -lkdeui 
        -lkparts

我已经安装了所有必需的库。证明:

nm -D /usr/lib/libkdeui.so | grep openWallet的输出为:

000000000032DF70 T _ZN7KWallet6Wallet10openWalletERK7QStringmNS0_8OpenTypeE

如您所见,libkdeui.so 文件中有该功能。 ^^

我已经安装了具有以下功能的库:

sudo apt-get install kdelibs5-dev libkparts4

有人可以告诉我我做错了什么吗?错误在哪里?

SSCCE:

#include <QCoreApplication>
#include <KWallet/Wallet>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    using namespace KWallet;
    Wallet* wallet = Wallet::openWallet(Wallet::LocalWallet(), 0);
    return a.exec();
}

.pro文件:

QT       += core 
TARGET = untitled
TEMPLATE = app
SOURCES += main.cpp
LIBS += -lkdeui -lkdecore -lkparts
INCLUDEPATH += /usr/include/KDE 
               /usr/include/KDE/KWallet

汇编:

g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_DBUS_LIB -DQT_CORE_LIB -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -I. -I/usr/include/KDE -I/usr/include/KDE/KWallet -ITDIR/include/QtGui -ITDIR/include -I. -o main.o main.cpp

g++ -m64 -wl,-O1 -o untitled main.o -L/usr/lib -L/usr/X11R6/lib64 -lkdeui -lkdecore -lkparts -L/usr/lib/x86_64-linux-gnu -lGL -lpthread

你的主要问题是你把Qt 5和KDE Frameworks 5混为一谈。那不会那样飞。自己看看这个:

KDE 4 related linkage: -lkdeui -lkdecore -lkparts
Qt 5 related linkage: -lQt5Widgets -lQt5Gui -lQt5Core

修复相对简单:

LIBS += -lkdecore -lkparts -lKF5Wallet
                           ^^^^^^^^^^^

当然,如果您转到 KF5,您还需要将包含路径更改为:

INCLUDEPATH += 
    ...
    /usr/include/KF5 
    /usr/include/KF5/KWallet/ 
    ...

如果您使用的是Qt 5和KF 5,则需要链接到该库。基本上,你使用的是 kde 4,因为 kdeui 是一个 KDE 4 库。您可以通过发出以下命令自行检查:

dpkg -S /usr/lib/libkdeui.so

简而言之,WId unsigned long在 kdeui 库中,因为这是 X11 平台上用于此目的的内容,而 Qt 5 混合可能以某种方式混淆了quintptr WId。虽然Qt 4的WId对于不同的平台是不同的,但Qt 5的WId是quintptr的,所以这更清楚。

如果你打算在KDE 4中使用Qt 4,

你的初始代码是可以的,但你需要确保在这种情况下运行Qt 4的qmake,而不是Qt 5的。这可以通过使用 qtchooser 或直接运行正确的 qmake 二进制文件。 qmake --version始终是您验证正在运行的版本的朋友。在我的 Debian 和 Archlinux 上,相应的 qmake 二进制文件称为 qmake-qt4

附带说明一下,奇怪的是,您添加了widgets模块,但您希望删除gui,而前者取决于后者。看过项目文件中使用的widgets模块后,我的观点更加明确,您可能希望此时使用 Qt 5 和 KF 5 组合。

这是我的工作Qt 5和KF 5测试片段:

主.cpp

#include <QCoreApplication>
#include <KWallet>
using KWallet::Wallet;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    KWallet::Wallet* wallet = Wallet::openWallet(Wallet::LocalWallet(), 0);
    return a.exec();
}

main.pro

TARGET = kwallet-test
TEMPLATE = app
SOURCES += main.cpp
LIBS += -lKF5Wallet
INCLUDEPATH += /usr/include/KF5/KWallet

qmake && make

为了在 Ubuntu 上运行,您需要安装以下添加到 Utopic (14.10) 的软件包:

sudo apt-get install libkf5wallet-dev

不幸的是,Trusty Tahr (14.04) 没有这个可用,但如果你愿意,你可以向后移植它。

在你从库中识别出的损坏名称上运行 c++filt 会得到: $ c++filt _ZN7KWallet6Wallet10openWalletERK7QStringmNS0_8OpenTypeE KWallet::Wallet::openWallet(QString const&, unsigned long, KWallet::Wallet::OpenType)

请注意,此处第二个参数的类型(无符号长整型)与您为 KWallet::Wallt::openWallet 提供的声明不匹配,该声明需要无符号长整型。这些不是同一类型。

编辑:示例:

#include <cstdio>
class QString;
namespace KWallet {
class  __attribute__((__visibility__("default"))) Wallet {
public:
    enum OpenType {
       whatever
    };
    void openWallet(QString const&, unsigned long, OpenType);

    void openWallet(QString const&, unsigned long long, OpenType);
};
}
void KWallet::Wallet::openWallet(QString const&, unsigned long, OpenType) {
   printf("unsigned longn");
}
void KWallet::Wallet::openWallet(QString const&, unsigned long long, OpenType) {
    printf("unsigned long longn");
}

编译到共享库:

g++ ./madeup.cpp -shared -fPIC

请注意,符号的混合方式不同: nm --dynamic --defined-only ./a.out 0000000000002020 A __bss_start 0000000000002020 A _edata 0000000000002021 A _end 00000000000007d4 T _fini 0000000000000638 T _init 0000000000000786 T _ZN7KWallet6Wallet10openWalletERK7QStringmNS0_8OpenTypeE 00000000000007ac T _ZN7KWallet6Wallet10openWalletERK7QStringyNS0_8OpenTypeE

管道通过C++滤液: m --dynamic --defined-only ./a.out | c++filt 0000000000002020 A __bss_start 0000000000002020 A _edata 0000000000002021 A _end 00000000000007d4 T _fini 0000000000000638 T _init 0000000000000786 T KWallet::Wallet::openWallet(QString const&, unsigned long, KWallet::Wallet::OpenType) 00000000000007ac T KWallet::Wallet::openWallet(QString const&, unsigned long long, KWallet::Wallet::OpenType)

应用程序看到的原型的损坏名称与正在链接的共享库中的损坏名称不匹配。