Ошибка связывания: неопределенная ссылка

Мой компилятор сообщает об этой неопределенной ссылке на 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
пароль_клиента «ВСЕ * .o ФАЙЛЫ» -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 без названия main.o -L / usr / lib -L / usr / X11R6 / lib64
-lkdeui -lkdecore -lkparts -L / usr / lib / x86_64-linux-gnu -lGL -lpthread

4

Решение

Ваша главная проблема заключается в том, что вы смешиваете 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

Короче говоря, WId было unsigned long в библиотеке kdeui, так как именно это использовалось для этого на платформах X11, тогда как смесь Qt 5, возможно, запутала quintptr в течение WIdкак-то. В то время как WId в Qt 4 был разным для разных платформ, WId в Qt 5 quintptrтак что понятнее.

Если вы планируете использовать Qt 4 с KDE 4, ваш исходный код в порядке, но вы должны убедиться, что в этом случае вы запускаете Qmake Qt 4, а не Qt 5. Это может быть либо с помощью 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) этого не было, но вы можете сделать это, если хотите.

1

Другие решения

Запуск с ++ фильтрования над искаженным именем, которое вы определили из библиотеки, дает:

$ c++filt
_ZN7KWallet6Wallet10openWalletERK7QStringmNS0_8OpenTypeE
KWallet::Wallet::openWallet(QString const&, unsigned long, KWallet::Wallet::OpenType)

Обратите внимание, что тип второго параметра (unsigned long) не соответствует объявлению, которое вы указали для 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 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

Трубопровод через С ++ фильт:

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

По вопросам рекламы [email protected]