Russian Qt Forum
Ноябрь 23, 2024, 18:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: DLL. Простые вопросы по изъеженной теме.  (Прочитано 10383 раз)
Bepec
Гость
« : Апрель 27, 2012, 12:48 »

Уважаемые знатоки, приветствую.

Понадобилось неожиданно мне проникнуться мудростью создания dll  и внедрения в них добрых функций и классов.
Почитал я форум. Не понял. Почитал темы. Не понял. Почитал ещё. Не понял.

Собственно вопросы:
  • Есть 2 типа dll (статические(lib), динамические(dll)). Но получается, для подключения каждого типа, необходим h файл, подключенный к проекту?
    Что вообще для этого подключения надо (в моём мозгу создавалось впечатление, что достаточно одной dll...)
  • Создание класса из dll. Не нашёл нормального примера, или пояснения (облом у меня в знаниях Оо)
  • Чтобы создать класс, объявленный в dll, необходимо сначала создать указатель на этот класс. Как и откуда его получить? (получается из h файла чтоли?)   
  • И ЧЯДНТ в нижеприведённом проекте?

dll.cpp
Код:
#include "tstdll.h"

tstDll::tstDll()
{
   
}

tstDll::~tstDll()
{

}

void tstDll::dd()
{
    QWidget *k = new QWidget(0);
    k->show();
    k->setStyleSheet("background-color:red;");

}
dll.h
Код:
#ifndef TSTDLL_H
#define TSTDLL_H

#include "tstdll_global.h"
#include <QWidget>


 extern "C" class TSTDLL_EXPORT tstDll
{
public:
    tstDll();
    ~tstDll();
    void dd();
private:

};

#endif // TSTDLL_H
program.cpp
Код:
#include "tstdllload.h"

tstDllLoad::tstDllLoad(QWidget *parent, Qt::WFlags flags)
    : QWidget(parent, flags)
{
    ui.setupUi(this);
    myLib.setFileName("tstDll");
    bool b = myLib.load();
    typedef tstDll (*dd)();
    dd myFunction = (dd) myLib.resolve("tstDll");
    if (myFunction)
        myFunction();
}

tstDllLoad::~tstDllLoad()
{

}
program.h
Код:
#ifndef TSTDLLLOAD_H
#define TSTDLLLOAD_H

#include <QtGui/QWidget>
#include "ui_tstdllload.h"
#include <QLibrary>

class tstDllLoad : public QWidget
{
    Q_OBJECT

public:
    tstDllLoad(QWidget *parent = 0, Qt::WFlags flags = 0);
    ~tstDllLoad();

private:
    Ui::tstDllLoadClass ui;
    QLibrary myLib;
};

#endif // TSTDLLLOAD_H
Записан
alexis031182
Гость
« Ответ #1 : Апрель 27, 2012, 13:39 »

Есть 2 типа dll (статические(lib), динамические(dll)). Но получается, для подключения каждого типа, необходим h файл, подключенный к проекту?
Для динамически подключаемых не обязателен.

Что вообще для этого подключения надо (в моём мозгу создавалось впечатление, что достаточно одной dll...)
Для динамически подключаемых - да.

Создание класса из dll. Не нашёл нормального примера, или пояснения (облом у меня в знаниях Оо)
Если требуется подключение произвольного (не библиотечного, вроде QObject или QWidget) класса из dll, то заголовочный файл потребуется присоединить к проекту. Лучше всего в нём объявить интерфейс (виртуальный класс), от которого в dll-ке унаследовать экспортируемый. Для примера можно посмотреть Plug&Paint.

Чтобы создать класс, объявленный в dll, необходимо сначала создать указатель на этот класс. Как и откуда его получить? (получается из h файла чтоли?)
В этом случае в dll-ке должна быть экспортируемая функция, которая будет создавать и возвращать новый объект класса.

И ЧЯДНТ в нижеприведённом проекте?
Функция dd должна быть вне класса, и именно её надо экспортировать.
Записан
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #2 : Апрель 27, 2012, 13:46 »

Код
C++ (Qt)
  myLib.setFileName("tstDll");
   bool b = myLib.load();
   typedef tstDll (*dd)();
   dd myFunction = (dd) myLib.resolve("tstDll");
   if (myFunction)
   myFunction();
Ты пытаешься вытащить из tstDll.dll (tstDll.so) глобальную функцию tstDll tstDll(), которой у тебя нет. Через
Код
C++ (Qt)
void* QLibrary::resolve (const char *symbol)
можно вытаскивать только С функции. Хочешь вытащить какой-нибудь класс - нужно объявить в подключаемой библиотеке функцию, которая будет возвращать пустой указатель на нужный класс.
Код
C++ (Qt)
void* getMyClass(int param);
а затем приводить уже к нужному классу и использовать.
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
Bepec
Гость
« Ответ #3 : Апрель 27, 2012, 14:07 »

Цитировать
Цитировать
Чтобы создать класс, объявленный в dll, необходимо сначала создать указатель на этот класс. Как и откуда его получить? (получается из h файла чтоли?)
В этом случае в dll-ке должна быть экспортируемая функция, которая будет создавать и возвращать новый объект класса.
Не осознал - для её получения, необходимо создать указатель этого класса. Дабы получить доступ к его методам. Но откуда его взять???

Проще:
Код:
void * func = <какая то функция>
// а далее надо получить тип класса, допустим  "tstDll", но его то я незнаю. Откуда его взять?
<???>tstDll</???> * funcDll = *func;

Принцип с классами в принципе ясен (получается как раз плагин), т.е. все классы находящиеся в dll должны быть наследниками 1 класса, который определён в программе и она его знает(может привести)

Но собственно ещё вопрос: Возможно ли создать самостоятельную dll ?

То есть не использовать его функции, а запустить её исполнение. Допустим спрятать в dll виджет с видео.


И таки ещё вопрос: Как можно из dll (исполняемой как раз), обмениваться информацией с другими процессами (и не Qt тоже)? (Вроде думается, что только пайпами (OS Windows)) ?


И ещё вопрос. Есть ли возможность именно создавать самостоятельные dll? К примеру 5 элементов - проигрыватель, панель, эффекты. Которые являтьяс будут разными dll, общающиеся между собой через *** (возможно пайпы).
Записан
alexis031182
Гость
« Ответ #4 : Апрель 27, 2012, 14:26 »

Не осознал - для её получения, необходимо создать указатель этого класса. Дабы получить доступ к его методам. Но откуда его взять???
Например, если это будет указатель на QObject, то *.h не нужен. Но в то же время, если возвращаемый из dll-ки класс унаследован от QObject (или вообще произвольный), то в этом случае без объявления такого класса в коде проекта не обойтись.

Если необходимо избавиться от *.h, то можно попробовать поступить так: из dll-ки возвращать QObject, а затем, через QMetaObject получать список методов класса.

Проще:
Код:
void * func = <какая то функция>
// а далее надо получить тип класса, допустим  "tstDll", но его то я незнаю. Откуда его взять?
<???>tstDll</???> * funcDll = *func;
В этом случае без *.h не обойтись.

Принцип с классами в принципе ясен (получается как раз плагин), т.е. все классы находящиеся в dll должны быть наследниками 1 класса, который определён в программе и она его знает(может привести)
Да, плагины этот принцип и используют. Только наследуется от интерфейса как правило лишь один класс в dll-ке, он как точка соприкосновения.

Но собственно ещё вопрос: Возможно ли создать самостоятельную dll ?
То есть не использовать его функции, а запустить её исполнение. Допустим спрятать в dll виджет с видео.
Если dll-ка самодостаточна, и ей не требуется взаимодействовать с загрузившим её приложением, то по идее достаточно одной экспортируемой функции.
Записан
Bepec
Гость
« Ответ #5 : Апрель 27, 2012, 14:33 »

Не могли бы вы привести пример "автономной" dll с одной экспортируемой функцией?

Записан
alexis031182
Гость
« Ответ #6 : Апрель 27, 2012, 15:12 »

START DLL PROJECT

dll.h
Код:
#ifndef DLL_H
#define DLL_H

#include <QObject>

#ifdef Q_WS_WIN
 #define MY_EXPORT __declspec(dllexport)
 #else
 #define MY_EXPORT
 #endif

extern "C" MY_EXPORT QObject *getObj();

#endif // DLL_H

dll.cpp
Код:
#include "dll.h"
#include <QDebug>

QObject *getObj()
{
QObject *obj = new QObject();
obj->setObjectName("tra-ta-ta");
qDebug() << "OK from DLL" << endl;
return obj;
}

END DLL PROJECT

START MAIN PROJECT

main.cpp
Код:
#include <QtCore/QCoreApplication>
#include <QLibrary>
#include <QDebug>

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QLibrary lib("filname.dll");
typedef QObject* (*MyPrototype)();
MyPrototype myFunction = (MyPrototype)lib.resolve("getObj");
if(myFunction) {
   QObject *obj = myFunction();
   qDebug() << obj->objectName() << endl;
}

return a.exec();
}
END MAIN PROJECT
Записан
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #7 : Апрель 27, 2012, 15:37 »

Не могли бы вы привести пример "автономной" dll с одной экспортируемой функцией?
Уже ответили, но продублирую
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
Bepec
Гость
« Ответ #8 : Апрель 27, 2012, 15:44 »

Благодарю за рабочий пример, очень помогли понять.

Следующий вопросик, точнее даже утверждение - в Дллке можно спокойно работать с классами и прочим.
Но. Но. Если дллку подключить к C/C++ чистому проекту, то при наличии необходимых библиотек логика dll отработает? (Qtшная?)

Проще говоря - будет ли работать программа, написанная на Qt, при наличии необходимых библиотек, вызванная из С/С++ чистой программы?

PS ну и грабли показывайте.
Записан
V1KT0P
Гость
« Ответ #9 : Апрель 27, 2012, 15:47 »

Благодарю за рабочий пример, очень помогли понять.

Следующий вопросик, точнее даже утверждение - в Дллке можно спокойно работать с классами и прочим.
Но. Но. Если дллку подключить к C/C++ чистому проекту, то при наличии необходимых библиотек логика dll отработает? (Qtшная?)

Проще говоря - будет ли работать программа, написанная на Qt, при наличии необходимых библиотек, вызванная из С/С++ чистой программы?

PS ну и грабли показывайте.

Я пихал графический виджет в С библиотеку, вызывал функции, грабил изображения и отдавал по запросу. Работает стабильно =).
Записан
alexis031182
Гость
« Ответ #10 : Апрель 27, 2012, 15:55 »

Благодарю за рабочий пример, очень помогли понять.
Я вдруг подумал, что это была проверка. Как в анекдоте про невидимого суслика Улыбающийся

Следующий вопросик, точнее даже утверждение - в Дллке можно спокойно работать с классами и прочим.
Но. Но. Если дллку подключить к C/C++ чистому проекту, то при наличии необходимых библиотек логика dll отработает? (Qtшная?)

Проще говоря - будет ли работать программа, написанная на Qt, при наличии необходимых библиотек, вызванная из С/С++ чистой программы?

PS ну и грабли показывайте.
Честно говоря, не могу утверждать на 100%, поскольку самолично такого не делал, но логика подсказывает, что всё будет в порядке. При минимуме взаимодействия (да даже и с полной интеграцией при должном внимании к коду) Qt-dll-ка будет работать как ей предписано.

Про грабли... может быть кто-нибудь ещё подскажет, реальны ли они в указанной ситуации в принципе.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Апрель 27, 2012, 16:17 »

Проще говоря - будет ли работать программа, написанная на Qt, при наличии необходимых библиотек, вызванная из С/С++ чистой программы?
Будет но толку от этого немного, т.к. из чистого хоста ни передать ни принять Qt объекты нельзя (ну разве как-то через void *)

А вот такое дело (никогда не понимал)
Код
C++ (Qt)
// export ф-ция MyLib.dll
 
int * GetData( void )
{
static int data;
return &data;
}
 
Теперь 2 разных хоста загрузили MyLib.dll. Что будет с данными на которые указывает data?
Записан
alexis031182
Гость
« Ответ #12 : Апрель 27, 2012, 16:25 »

Будет но толку от этого немного, т.к. из чистого хоста ни передать ни принять Qt объекты нельзя (ну разве как-то через void *)
Но речь ведь об этом и шла, чтобы минимум взаимодействия.

А вот такое дело (никогда не понимал)
...
Теперь 2 разных хоста загрузили MyLib.dll. Что будет с данными на которые указывает data?
Не будет работать? Похоже на... э-э-э... синглтон в dll-ке.
Записан
Bepec
Гость
« Ответ #13 : Апрель 27, 2012, 16:53 »

Нет, это не проверка (по секрету скажу  - [вырезано из соображений секретности] и конечно [вырезано из соображений секретности]).

Поняяяятненько. Далее вопросы конечно появятся, но не сегодня- завтра. Спасибо за отклик.
Записан
alexis031182
Гость
« Ответ #14 : Апрель 27, 2012, 17:46 »

Нет, это не проверка (по секрету скажу  - [вырезано из соображений секретности] и конечно [вырезано из соображений секретности]).
)))) Да, я уже заметил, сколько секретно-правительственных разрабов на этом форуме шифруется
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.196 секунд. Запросов: 23.