Russian Qt Forum

Qt => Общие вопросы => Тема начата: BaltikS от Октябрь 18, 2006, 11:06



Название: Как сделать DLL
Отправлено: BaltikS от Октябрь 18, 2006, 11:06
Помогите плиз....сижу туплю...
Как правильно создать класс (например QMyWidget) и запихнуть его в ДЛЛ... И как правильно этот виджет вызвать?

Сделал так:
Создал новый проект NEW SHARED LIBRARY...
Код:

#ifndef BMAP_H
#define BMAP_H

#include <QGraphicsView>
#include "canvlib_global.h"

class CANVLIB_EXPORT BMap : public QGraphicsView
{
public:
    BMap( QWidget * parent = 0 );
    ~BMap();

private:

};

#endif // BMAP_H

Получил ДЛЛ с ЛИБом. Подключаю ЛИБ к проекту....
Пишу строки в коде:
Код:

BMap *map = new BMap(this);
map->show();

Компилируется, линкуется... Но потом при старте приложения говорит "Не найдена точка входа"
Что делать?
____________________
Имею QT 4.2 + VS2005


Название: Re: Как сделать DLL
Отправлено: Maxz от Октябрь 18, 2006, 14:38
Цитата: "BaltikS"
Как правильно создать класс (например QMyWidget) и запихнуть его в ДЛЛ... И как правильно этот виджет вызвать?


Глянь в примерах examples/tools/plugandpaint и examples/tools/plugandpaintplugins - там что-то подобное сделано.


Название: Как сделать DLL
Отправлено: BaltikS от Октябрь 18, 2006, 15:04
Спасибо, глядел, это подключение плагина........
На самом деле всё получилось, как описано выше.... Только с пересозданием проекта.... Глюк наверное VS...


Название: Как сделать DLL
Отправлено: Admin от Октябрь 18, 2006, 18:31
обычно всякие макросы типа DLL_EXPORT пользуют


Название: Как сделать DLL
Отправлено: Lion от Октябрь 18, 2006, 22:54
Цитата: "Admin"
обычно всякие макросы типа DLL_EXPORT пользуют

А в Qt есть готовый макрос?


Название: Как сделать DLL
Отправлено: Admin от Октябрь 19, 2006, 07:56
нет, так как это специфично для каждой платформы

в Windows DLL_Export

в Linux вообще не надо

так что сам заведи макрос и в путь


Название: Как сделать DLL
Отправлено: nikolai98 от Октябрь 21, 2006, 00:52
Хелп, помогите.... Как сделать динамическую библиеотеку с классом от QWidget, так как написоно в первом сообщении, но для Qt 3... Весь ассистент перечитал, все варианты про переписал... Не получается... Либо создаётся LIB, либо DLL.... Либа линкуется только статически... Хелп...если можно на примере....


Название: Как сделать DLL
Отправлено: Dendy от Октябрь 21, 2006, 08:48
MyWidget.h
Код:

#prama once

#include <QWidget>

#if defined Q_WS_WIN
# ifdef MYWIDGET_STATIC
# define MYWIDGET_EXPORT
# else
# ifdef MYWIDGET_BUILD
# define MYWIDGET_EXPORT __declspec(dllexport)
# else
# define MYWIDGET_EXPORT __declspec(dllimport)
# endif
# endif
#else
# define MYWIDGET_EXPORT
#endif

// define MYWIDGET_STATIC - when MyWidget sources appended directly to the project
// define MYWIDGET_BUILD - when MyWidget builds as DLL
// no define needed, when MyWidget linked dynamicaly to the project from DLL

class MYWIDGET_EXPORT MyWidget : public QWidget
{
  Q_OBJECT

public:
  MyWidget( QWidget * parent = 0 );

// some useful code here
};



MyWidget.cpp
Код:

#include "MyWidget.h"

MyWidget::MyWidget( QWidget * parent ) :
  QWidget( parent )
{
  ...
}

...
// MyWidget methods definitions



MyWidget.pro // for DLL building
Код:
TEMPLATE = lib
DEFINES += MYWIDGET_BUILD
SOURCES = MyWidget.cpp
HEADERS = MyWidget.h


Название: Как сделать DLL
Отправлено: nikolai98 от Октябрь 21, 2006, 09:19
Dendy, спасибо за код, только он очень похож на DLL собранную в Qt4, а нужно для Qt3.... Ещё забыл упомянуть, что библиотеки надо собирать не только в Windows, но и в Linux... Извините за некоторый тупизм, но моих знаний никак не хватает :)


Название: Как сделать DLL
Отправлено: Admin от Октябрь 21, 2006, 09:25
смотри тут

#if defined Q_WS_WIN


Название: Как сделать DLL
Отправлено: nikolai98 от Октябрь 21, 2006, 09:59
В результате сборки я получил опять статическую LIB! А мне нужно DLL!!!!! и эту ДЛЛ потом подключать к другим проектам. А полученая ЛИБ линкуется опять только статически!!!


Название: Как сделать DLL
Отправлено: Dendy от Октябрь 21, 2006, 12:25
ВсмьІсле статически линкуется с либами Qt? Или DLL вообще нет? Может забьІл дописать в проект:

Код:
TEMPLATE = lib
CONFIG += dll


Название: Как сделать DLL
Отправлено: nikolai98 от Октябрь 21, 2006, 13:12
Слушай, ты гений! Тебе надо памятник поставить.... Огромное спасибо!


Название: Как сделать DLL
Отправлено: Lion от Октябрь 27, 2006, 14:47
Сделал как написано, получил dll, а как теперь научить другие проекты ею пользоваться? При компиляции сплошные ошибки типа этой:
Код:

Error 15 error LNK2019: unresolved external symbol "__declspec(dllimport) public: class QString const __thiscall ErrorHandler::message(void)const " (__imp_?message@ErrorHandler@@QBE?BVQString@@XZ) referenced in function "public: virtual bool __thiscall IqAuth::hookElement(class QDomElement *)" (?hookElement@IqAuth@@UAE_NPAVQDomElement@@@Z) iqauth.obj


Название: Как сделать DLL
Отправлено: Admin от Октябрь 27, 2006, 14:51
все экспортируем функции должны быть обьявлены как __declspec(dllexport)


Название: Как сделать DLL
Отправлено: BaltikS от Октябрь 27, 2006, 17:18
Такое  ощущение, что ты к проекту LIB забыл подключить....


Название: Как сделать DLL
Отправлено: Lion от Октябрь 28, 2006, 09:51
Цитата: "BaltikS"
Такое  ощущение, что ты к проекту LIB забыл подключить....

Никакого lib не появилось. Как его подключить?


Название: Как сделать DLL
Отправлено: Dendy от Октябрь 28, 2006, 13:12
Рядом с myapp.dll создаётся myapp.lib, но только если у тебя експортится из DLL хотя-бьІ один символ.

Смотри мой пост ранее. Класс експортится примерно таким способом:

Код:
#if defined Q_WS_WIN 
#   ifdef MYWIDGET_STATIC
#      define MYWIDGET_EXPORT
#   else
#      ifdef MYWIDGET_BUILD
#         define MYWIDGET_EXPORT __declspec(dllexport)
#      else
#         define MYWIDGET_EXPORT __declspec(dllimport)
#      endif
#   endif
#else
#   define MYWIDGET_EXPORT
#endif

class MYWIDGET_EXPORT MyWidget : public QWidget
...


При етом в файле проекта, которьІй создаёт DLL должен стоять макрос DEFINES += MYWIDGET_BUILD, что означает применение к данному классу експортирования: MYWIDGET_EXPORT == __declspec(dllexport).

В файле проекта программьІ, в которой тьІ используешь оную DLL не ставишь никаких макросов. Ето приводит к тому, что заголовочник для компиллятора будет вьІглядеть по-другому. А именно: MYWIDGET_EXPORT == __declspec(dllimport). В результате линковщик будет импортировать етот класс.


Название: Как сделать DLL
Отправлено: crocus от Октябрь 28, 2006, 14:30
А порекомендуй, где про это можно почитать, для систематизированного понимания??


Название: Как сделать DLL
Отправлено: Dendy от Октябрь 28, 2006, 14:38
Для виндьІ В MSDN наверное ;)  Да и просматривать исходники Qt никогда не мешает.


Название: Как сделать DLL
Отправлено: Lion от Октябрь 28, 2006, 15:25
Всё сделал как написано, только либ не увидел. Теперь
её подключил, все классы линкуются а отдельные функции нет. Делаю так:
Код:

UTILS_EXPORT int SHA1Hash(SHA1Context *, const unsigned char *, unsigned);


где UTILS_EXPORT = MYWIDGET_EXPORT


Название: Как сделать DLL
Отправлено: Вячеслав от Октябрь 28, 2006, 16:40
Цитата: "Lion"
Всё сделал как написано, только либ не увидел. Теперь
её подключил, все классы линкуются а отдельные функции нет. Делаю так:
Код:

UTILS_EXPORT int SHA1Hash(SHA1Context *, const unsigned char *, unsigned);


где UTILS_EXPORT = MYWIDGET_EXPORT

Функция не из C-linkage случаем ?
i.e. extern "C" не надо ?
Код:

extern "C" UTILS_EXPORT int SHA1Hash(SHA1Context *, const unsigned char *, unsigned);


Название: Как сделать DLL
Отправлено: Lion от Октябрь 28, 2006, 21:23
Для полной ясности привожу исходные коды
Код:
#ifndef UTILS_EXPORT

# if defined Q_WS_WIN
#   ifdef UTILS_STATIC
#     define UTILS_EXPORT  //Static link
#   else
#     ifdef UTILS_DLL
#       define UTILS_EXPORT __declspec(dllexport)  //Dynamic link
#     else
#       define UTILS_EXPORT __declspec(dllimport)  //Import from dll
#     endif
#   endif
# else
#   define UTILS_EXPORT  //Linux
# endif


#endif //UTILSEXPORT_H


Код:
#ifndef _SHA1_H_
#define _SHA1_H_

#include "utilsexport.h"

/*
 *  This structure will hold context information for the hashing
 *  operation
 */
typedef struct SHA1Context
{
    unsigned Message_Digest[5]; /* Message Digest (output)          */

    unsigned Length_Low;        /* Message length in bits           */
    unsigned Length_High;       /* Message length in bits           */

    unsigned char Message_Block[64]; /* 512-bit message blocks      */
    int Message_Block_Index;    /* Index into message block array   */

    int Computed;               /* Is the digest computed?          */
    int Corrupted;              /* Is the message digest corruped?  */
} SHA1Context;

#ifdef __cplusplus
extern "C" {
#endif

/*
 *  Function Prototypes
 */

UTILS_EXPORT void SHA1Reset(SHA1Context *);
UTILS_EXPORT void SHA1Input(SHA1Context *, const unsigned char *, unsigned);
UTILS_EXPORT int SHA1Result(SHA1Context *);
UTILS_EXPORT int SHA1Hash(SHA1Context *, const unsigned char *, unsigned);
UTILS_EXPORT int SHA1Hex(const SHA1Context *context, char *hex);

#ifdef __cplusplus
}
#endif

#endif


добавлено спустя 7 минут:

 Для проекта библиотеки определено UTILS_DLL


Название: Как сделать DLL
Отправлено: Dendy от Октябрь 28, 2006, 21:58
А реализации етих не-линкующихся функций присутствуют? Уверен, что не ошибся ни в одной букве функции в CPP-файле? Компиллятор ведь промолчит.

Кроме того, всегда можно посмотреть что експортится сторонними утилитами.


Название: Как сделать DLL
Отправлено: Lion от Октябрь 28, 2006, 22:22
До этого все успешно линковалось статически


Название: Как сделать DLL
Отправлено: Lion от Ноябрь 03, 2006, 21:10
Как всегда всё оказалось проще чем казалось, просто Q_WS_WIN определяется в qglobal.h, а в моем случае макрос инклудился вперед всех qt -шных модулей. #include <QObject> в макросе решило все проблемы.