链接错误:未定义的引用

时间:2014-11-25 14:59:06

标签: c++ linux compiler-errors g++ kde

我的编译器报告此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

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

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无标题main.o -L / usr / lib -L ​​/ usr / X11R6 / lib64   -lkdeui -lkdecore -lkparts -L / usr / lib / x86_64-linux-gnu -lGL -lpthread

2 个答案:

答案 0 :(得分:1)

在您从库中识别的错位名称上运行c ++ filt会给出: $ c++filt _ZN7KWallet6Wallet10openWalletERK7QStringmNS0_8OpenTypeE KWallet::Wallet::openWallet(QString const&, unsigned long, KWallet::Wallet::OpenType)

请注意,此处第二个参数的类型(unsigned long)与您为KWallet::Wallt::openWallet提供的声明不匹配,后者需要一个unsigned long long。这些不是同一类型。

编辑:示例:

#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 long\n");
}

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

编译到共享库:

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)

应用程序看到的原型的错位名称与链接的共享库中的错位名称不匹配。

答案 1 :(得分:1)

你的主要问题是你将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改为:

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

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

dpkg -S /usr/lib/libkdeui.so

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

如果您计划将Qt 4与KDE 4一起使用,那么您的初始代码就可以了,但是您需要确保在这种情况下运行Qt 4的qmake,而不是Qt 5&#39。这可以通过使用qtchooser或直接运行正确的qmake二进制文件。 qmake --version始终是您的朋友,以验证正在运行的版本。在我的Debian和Archlinux上,相应的qmake二进制文件称为qmake-qt4

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

这是我正在使用的Qt 5和KF 5测试片段:

的main.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)没有提供此功能,但如果您愿意,也可以向后移植。