crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Динамические библиотеки QT
theravel
  опции профиля:
сообщение 24.1.2010, 15:24
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 24.1.2010
Пользователь №: 1400

Спасибо сказали: 0 раз(а)




Репутация:   0  


День добрый,
сразу прошу простить за весьма ламерский вопрос, на QT пробую кодить второй день, и все два дня посвятил созданию простого примера с динамическими библиотеками.
Пытаюсь повторить этот пример, но он то не компилируется, то загрузка плагина не происходит

Вообщем мой вопрос в том, почему так, что неправильно,
и еще я буду безумно благодарен, если кто-то выложит не отдельно файлики проекта, а весь проект с любым плагином целиком

Собираю в Qt Creator 1.3.0 (Qt 4.6.0) (32-х битной) Windows7

Мой проект выглядит как-то так:

файл plugin/interface.h
#ifndef INTERFACE_H
#define INTERFACE_H

#include <QString>

class Base
{
public:
    virtual QString echo();
};

Q_DECLARE_INTERFACE(Base,"com.trolltech.Plugin.Base/1.0");

#endif


Кусок файла plugin/mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QDir pluginsDir(qApp->applicationDirPath());
    Base *interface;
    pluginsDir.cd("plugins");
    foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
         QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
         if (pluginLoader.isLoaded())
             QMessageBox::information(this,"caption","yes");
         else
             QMessageBox::information(this,"caption","no");
         QObject *plugin = pluginLoader.instance();
         if (plugin) {
             interface = qobject_cast<Base *>(plugin);
         }
    }
}


Файл plugin/plugin.pro
TARGET = plugin
TEMPLATE = app
SOURCES += main.cpp \
    mainwindow.cpp
HEADERS += mainwindow.h \
    interface.h
FORMS += mainwindow.ui


Файл plugin/dynamic2/dynamic2.h
#ifndef DYNAMIC_H
#define DYNAMIC_H

#include <QObject>
#include "dynamic2.h"
#include "../interface.h"

class Q_DECL_EXPORT Plugin : public QObject, Base
{
    Q_OBJECT
    Q_INTERFACES(Base)
public:
    QString echo();
};

#endif // DYNAMIC_H


Файл plugin/dynamic2/dynamic2.cpp
#include <QtGui>
#include "dynamic2.h"

QString Plugin::echo()
{
    return "some string";
}

Q_EXPORT_PLUGIN2(myplugin, Plugin);


Файл plugin/dynamic2/dynamic2.pro
TARGET = $$qtLibraryTarget(myplugin)
TEMPLATE = lib

DEFINES += DYNAMIC2_LIBRARY

SOURCES += dynamic2.cpp

HEADERS += dynamic2.h\
        dynamic2_global.h
CONFIG += shared



При этом проект dynamic2 не компилируется с ошибкой
D:\Tools\QT\plugin\dynamic2/../interface.h:7: undefined reference to `vtable for Base'
:-1: error: collect2: ld returned 1 exit status

Но, если в dynamic.pro выставить CONFIG += release, то dll компилируется
Но, даже если проект plugin собрать в режиме релиза, и положить получившуюся dll в нужную папку (пути верны, я проверял), то все равно приложение при запуске покажет сообщение "no" - плагин не загружен

Весь проект лежит здесь
Еще раз скажу, что буду безумно благодарен скомпонованному проекту с любым плагином.
С уважением, Дмитрий
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 24.1.2010, 15:56
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


У QPluginLoader есть метод:
QString QPluginLoader::errorString () const

Собирай и плагин и программу в чем то одном, или debug или release.
В pro файлы проектов добавь:
CONFIG += release

Сделай в обоих проектах
make distclean
qmake
make

и все заработает. :)

Еще я бы добавил:
class Base
{
public:
    virtual QString echo() = 0;
};
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
theravel
  опции профиля:
сообщение 24.1.2010, 17:00
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 24.1.2010
Пользователь №: 1400

Спасибо сказали: 0 раз(а)




Репутация:   0  


Так, если по порядку,

Добавил это
class Base
{
public:
    virtual QString echo() = 0;
};

теперь библиотека компилируется без ошибок, отлично =)

Цитата
В pro файлы проектов добавь:
CONFIG += release

Сделай в обоих проектах
make distclean
qmake
make

сделал, но при запуске приложения библиотека не загружается, а QPluginLoader::errorString() выдает "unknown error"
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 24.1.2010, 17:34
Сообщение #4


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Для вывода отладочной информации плагинов можно использовать QT_DEBUG_PLUGINS=1.
Тебе нужно установить этот параметр в настройках Qt Creator'a, правда не знаю где, так как нет его под рукой...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 24.1.2010, 17:59
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(theravel @ 24.1.2010, 17:00) *
сделал, но при запуске приложения библиотека не загружается, а QPluginLoader::errorString() выдает "unknown error"

Ну значит все нормально:
ainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QDir pluginsDir(qApp->applicationDirPath());
    Base *interface;
    pluginsDir.cd("plugins");
    foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
         QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
         QObject *plugin = pluginLoader.instance();
         if (plugin) {
             interface = qobject_cast<Base *>(plugin);
             if( interface )
                 QMessageBox::information(this,"caption", interface->echo() );
         }
    }
}


Сообщение отредактировал BRE - 24.1.2010, 18:04
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
theravel
  опции профиля:
сообщение 24.1.2010, 22:28
Сообщение #6


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 24.1.2010
Пользователь №: 1400

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(BRE @ 24.1.2010, 17:59) *
Ну значит все нормально:


Заработало, действительно)) спасибо!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
theravel
  опции профиля:
сообщение 25.1.2010, 22:02
Сообщение #7


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 24.1.2010
Пользователь №: 1400

Спасибо сказали: 0 раз(а)




Репутация:   0  


Тогда еще один вопрос, просто из любопыства,

class Base
{
public:
    virtual QString echo() = 0;
};


что значит этот ноль? где можно почитать про такие конструкции?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 25.1.2010, 22:22
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(theravel @ 25.1.2010, 22:02) *
что значит этот ноль? где можно почитать про такие конструкции?

Определение чисто виртуальной функции (pure virtual).
Почитать можно в книгах по C++.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.1.2010, 7:05
Сообщение #9


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(theravel @ 26.1.2010, 1:02) *
что значит этот ноль?
Цитата(BRE @ 26.1.2010, 1:22) *
Определение чисто виртуальной функции (pure virtual).
Добавлю:
класс который содержит истинно-виртуальную функцию обычно называют - абстрактным, т.к. нельзя создать экземпляр такого класса (истинно-виртуальная функция не имеет реализации). Абстрактные классы предназначены только для наследования.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 17:16