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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Подскажите как реализовать в дллсвой класс?  (Прочитано 7547 раз)
lolbla2
Гость
« : Февраль 22, 2012, 17:06 »

Хочу сделать свой класс в длл и чтобы длл можно было подключать динамически, то есть не прописывать файле проекта её, а подключать при помощи например QLibrary::load() или же аналог Winapi LoadLibrary. Возможно ли так сделать? а то у меня так получается только с функциями, а с классами никак, экспорт классов как реализовать? Может мне надо использовать плагины? Но в плагинах же вроде можно только отнаследовать стандартные Qt классы? А если мне надо с нуля свой класс сделать и чтобы потому в программе подключить эту длл и создавать объекты этого класса таким образом  
Код:
Myclass obj;
 

P.S. Давно эта проблема интересует, но раньше как-то забил на это не получилось и фиг с ним, а ща снова заинтересовался как так сделать...
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Февраль 22, 2012, 18:00 »

Блжад, а поискать по форуму не судьба?  Злой
Записан

ArchLinux x86_64 / Win10 64 bit
lolbla2
Гость
« Ответ #2 : Февраль 22, 2012, 18:48 »

Блжад, а поискать по форуму не судьба?  Злой

 подходящего не нашёл. Если знаешь по теме ответь.
Записан
Ground
Гость
« Ответ #3 : Февраль 23, 2012, 04:37 »

Тут нужно смотреть, знает ли приложение, к которому ты подключаешь DLL Qt или нет. Если не знает, то нужно делать интерфейс для класса, из которого убирать все упоминания о Qt, вот примерно так:
Код
C++ (Qt)
#ifdef ICLIENT_EXPORTS
#define ICLIENT_API __declspec(dllexport)
#else
#define ICLIENT_API __declspec(dllimport)
#endif
 
class ICLIENT_API IClient {
public:
   // Конструктор
   IClient();
   // Деструктор
   ~IClient();
 
   // Метод, выполняющий попытку подключения к серверу
   int connectToServer();
   // Принудительное отключение клиента
   int disconnectFromServer();
 
   // Установка сетевых настроек для клиента
   int setParameters(char* serverAddress, int port);
 
   // Состояние клиента
   int isConnected();
 
   // Отправка сообщения серверу о готовности клиента к получению данных
   int sendClientIsReady();
   // Отправка пакета с информацией об имени отображаемого в память файла
   int sendMMFPackage(char* MMFName);
   // Отправка данных об элементе для регистрации на сервере
   int sendRegInfoPackage(int elementID, int count,
                          int* startBytes, int* bytesCount);
   // Отправка запроса на получение описания к элементу
   int sendDBRequestPackage(int elementID, int startByte,
                            int startBit, int bitsCount);
   // Установка буфера для сброса полученной информации
   int setBuffer(char* buffer);
 
   // Обработка событий сети
   int start();
 
private:
   Client* mClient;
   char* mBuffer;
};
 
Везде инты, чары - благодать. А Qt будет работать в классе Client, он тут объявлен как указатель, в конструкторе класса создается. CPP-файл заполняется как обычно, никаких особенностей там нет.
Только есть один момент, если у тебя в DLL есть что-то, отправляющее сигналы (сеть, например), то работать это не будет, пока ты в программе, к которой подключаешь DLL не создашь QCoreApplication или QApplication.

Потом компилишь свою либу, получаешься на выходе, для винды: lib + dll. Либ явно подключаешь к проекту LIBS += твоя_либа. В сам код делаешь #include "твоя_либа.h", все, можешь в коде делать экземпляр своего класса из либы и работать.
Записан
lolbla2
Гость
« Ответ #4 : Февраль 23, 2012, 09:35 »

Тут нужно смотреть, знает ли приложение, к которому ты подключаешь DLL Qt или нет. Если не знает, то нужно делать интерфейс для класса, из которого убирать все упоминания о Qt, вот примерно так:
Код
C++ (Qt)
#ifdef ICLIENT_EXPORTS
#define ICLIENT_API __declspec(dllexport)
#else
#define ICLIENT_API __declspec(dllimport)
#endif
 
class ICLIENT_API IClient {
public:
   // Конструктор
   IClient();
   // Деструктор
   ~IClient();
 
   // Метод, выполняющий попытку подключения к серверу
   int connectToServer();
   // Принудительное отключение клиента
   int disconnectFromServer();
 
   // Установка сетевых настроек для клиента
   int setParameters(char* serverAddress, int port);
 
   // Состояние клиента
   int isConnected();
 
   // Отправка сообщения серверу о готовности клиента к получению данных
   int sendClientIsReady();
   // Отправка пакета с информацией об имени отображаемого в память файла
   int sendMMFPackage(char* MMFName);
   // Отправка данных об элементе для регистрации на сервере
   int sendRegInfoPackage(int elementID, int count,
                          int* startBytes, int* bytesCount);
   // Отправка запроса на получение описания к элементу
   int sendDBRequestPackage(int elementID, int startByte,
                            int startBit, int bitsCount);
   // Установка буфера для сброса полученной информации
   int setBuffer(char* buffer);
 
   // Обработка событий сети
   int start();
 
private:
   Client* mClient;
   char* mBuffer;
};
 
Везде инты, чары - благодать. А Qt будет работать в классе Client, он тут объявлен как указатель, в конструкторе класса создается. CPP-файл заполняется как обычно, никаких особенностей там нет.
Только есть один момент, если у тебя в DLL есть что-то, отправляющее сигналы (сеть, например), то работать это не будет, пока ты в программе, к которой подключаешь DLL не создашь QCoreApplication или QApplication.

Потом компилишь свою либу, получаешься на выходе, для винды: lib + dll. Либ явно подключаешь к проекту LIBS += твоя_либа. В сам код делаешь #include "твоя_либа.h", все, можешь в коде делать экземпляр своего класса из либы и работать.

Вы меня немного не поняли.... lib это статическая версия библиотеки, а я говорю о динамике, чтобы никаких LIBS +=... в проекте делать не надо было, у меня к примеру есть толькo .dll.

Например есть Mydll.dll. Там есть некоторый класс Myclass;

подключаю её следующим образом:
Код:
QLibrary lib;
lib.load("Mydll.dll);

И далее хочу создать экземпляр класса:

Код:
Myclass obj;

Так вот при динамике так не получается, если .lib подрубить да ещё и .h файл длл это уже статическое подключение, а я говорю о ДИНАМИКЕ. Про то что ты мне сказал это я и так знаю что так будет работать.

P.S. Вроде надо ещё дописывать extern "C" перед __declspec(dllexport),а то иначе чото он вроде не пашет по крайне мере в MSVS
« Последнее редактирование: Февраль 23, 2012, 09:38 от lolbla2 » Записан
Ground
Гость
« Ответ #5 : Февраль 23, 2012, 10:34 »

Вы меня немного не поняли.... lib это статическая версия библиотеки, а я говорю о динамике, чтобы никаких LIBS +=... в проекте делать не надо было, у меня к примеру есть толькo .dll.

Например есть Mydll.dll. Там есть некоторый класс Myclass;

подключаю её следующим образом:
Код:
QLibrary lib;
lib.load("Mydll.dll);

И далее хочу создать экземпляр класса:

Код:
Myclass obj;

Так вот при динамике так не получается, если .lib подрубить да ещё и .h файл длл это уже статическое подключение, а я говорю о ДИНАМИКЕ. Про то что ты мне сказал это я и так знаю что так будет работать.

P.S. Вроде надо ещё дописывать extern "C" перед __declspec(dllexport),а то иначе чото он вроде не пашет по крайне мере в MSVS

Lib тоже разный бывает. В одном случае там действительно объектный код функций (и тогда это статическая линковка), а иногда там просто указания для линкера, как ресолвить функции в dll.
Единственное, я копал про это для MSVC2010, не знаю как GCC себя ведет. UPD: Вспомнил, не далее как вчера пробовал в GCC такую же схему, подключил .a к проекту на чистом C++, хедер от этого класса. И дальше спокойно создавал объекты. Таким образом, вам даже можно обойтись без QLibrary, насколько я понимаю.

P.S. Вроде надо ещё дописывать extern "C" перед __declspec(dllexport),а то иначе чото он вроде не пашет по крайне мере в MSVS
Есть такое. Вот эти строчки:
Код
C++ (Qt)
#ifdef ICLIENT_EXPORTS
#define ICLIENT_API __declspec(dllexport)
#else
#define ICLIENT_API __declspec(dllimport)
#endif
А потом в хедере класса:
Код
C++ (Qt)
class ICLIENT_API IClient
{
   ...
}
« Последнее редактирование: Февраль 23, 2012, 10:38 от Ground » Записан
lolbla2
Гость
« Ответ #6 : Февраль 23, 2012, 10:41 »

Вы меня немного не поняли.... lib это статическая версия библиотеки, а я говорю о динамике, чтобы никаких LIBS +=... в проекте делать не надо было, у меня к примеру есть толькo .dll.

Например есть Mydll.dll. Там есть некоторый класс Myclass;

подключаю её следующим образом:
Код:
QLibrary lib;
lib.load("Mydll.dll);

И далее хочу создать экземпляр класса:

Код:
Myclass obj;

Так вот при динамике так не получается, если .lib подрубить да ещё и .h файл длл это уже статическое подключение, а я говорю о ДИНАМИКЕ. Про то что ты мне сказал это я и так знаю что так будет работать.

P.S. Вроде надо ещё дописывать extern "C" перед __declspec(dllexport),а то иначе чото он вроде не пашет по крайне мере в MSVS

Lib тоже разный бывает. В одном случае там действительно объектный код функций (и тогда это статическая линковка), а иногда там просто указания для линкера, как ресолвить функции в dll.
Единственное, я копал про это для MSVC2010, не знаю как GCC себя ведет. UPD: Вспомнил, не далее как вчера пробовал в GCC такую же схему, подключил .a к проекту на чистом C++, хедер от этого класса. И дальше спокойно создавал объекты. Таким образом, вам даже можно обойтись без QLibrary, насколько я понимаю.

P.S. Вроде надо ещё дописывать extern "C" перед __declspec(dllexport),а то иначе чото он вроде не пашет по крайне мере в MSVS
Есть такое. Вот эти строчки:
Код
C++ (Qt)
#ifdef ICLIENT_EXPORTS
#define ICLIENT_API __declspec(dllexport)
#else
#define ICLIENT_API __declspec(dllimport)
#endif
А потом в хедере класса:
Код
C++ (Qt)
class ICLIENT_API IClient
{
   ...
}

Нет такого, надо тогда хотя бы так писать
Код
C++ (Qt)
#ifdef ICLIENT_EXPORTS
#define ICLIENT_API extern "C" __declspec(dllexport)
#else
#define ICLIENT_API extern "C" __declspec(dllimport)
#endif
А потом в хедере класса:
Код
C++ (Qt)
class ICLIENT_API IClient
{
   ...
}
Ну это мелочи

А по-моему вопрос так нового ничего и не узнал к сожалению((( Понимаешь охото без подключения всяких .h файлов длл и без .lib работать с классами в .dll. Такое наверно невозможно?
Записан
Ground
Гость
« Ответ #7 : Февраль 23, 2012, 10:47 »

Ну это мелочи
Для студии да, ты все верно написал. А мой вариант - это макрос для Qt.

А по-моему вопрос так нового ничего и не узнал к сожалению((( Понимаешь охото без подключения всяких .h файлов длл и без .lib работать с классами в .dll. Такое наверно невозможно?
Ну вот статья, там про все это расписано: http://www.rsdn.ru/article/baseserv/dlluse.xml
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #8 : Февраль 23, 2012, 10:55 »

Понимаешь охото без подключения всяких .h файлов длл и без .lib работать с классами в .dll. Такое наверно невозможно?

То как ты хочешь - невозможно. Класс должен быть явным образом объявлен, чтобы использовать его в C++ коде именно так, как ты показал.

Теоретически, можно использовать Qt-шный metaobject и вызывать методы через него. Проблема в том, что класс должен быть заточен под это.
Записан
lolbla2
Гость
« Ответ #9 : Февраль 23, 2012, 11:22 »

Понимаешь охото без подключения всяких .h файлов длл и без .lib работать с классами в .dll. Такое наверно невозможно?

То как ты хочешь - невозможно. Класс должен быть явным образом объявлен, чтобы использовать его в C++ коде именно так, как ты показал.

Теоретически, можно использовать Qt-шный metaobject и вызывать методы через него. Проблема в том, что класс должен быть заточен под это.

то есть таким образом как я указал можно вызывать только функции из длл да? Чтобы работать с классами я должен явно подключать длл? Всё верно ? ну я так и думал.
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #10 : Февраль 23, 2012, 11:32 »

то есть таким образом как я указал можно вызывать только функции из длл да?

Грубо говоря - да. Не совсем понятно зачем это нужно, напиши пример использования.
Записан
lolbla2
Гость
« Ответ #11 : Февраль 23, 2012, 12:56 »

то есть таким образом как я указал можно вызывать только функции из длл да?

Грубо говоря - да. Не совсем понятно зачем это нужно, напиши пример использования.

Например хочу свой класс сделать чтобы его использовали другие люди, но чтобы ничего не меняли. А если .h файл доступен, то они могут например private функции сделать public
Записан
mutineer
Гость
« Ответ #12 : Февраль 23, 2012, 12:59 »

Например хочу свой класс сделать чтобы его использовали другие люди, но чтобы ничего не меняли. А если .h файл доступен, то они могут например private функции сделать public

Если они так сдлеают, то ССЗБ:) ну или можно по образу Qt оставить в .h только публичные методы
Записан
lolbla2
Гость
« Ответ #13 : Февраль 23, 2012, 13:45 »

Например хочу свой класс сделать чтобы его использовали другие люди, но чтобы ничего не меняли. А если .h файл доступен, то они могут например private функции сделать public

Если они так сдлеают, то ССЗБ:) ну или можно по образу Qt оставить в .h только публичные методы
а остальные куда деть тогда? Прямо внутри публичных функций что ли реализовывать?

P.S.: а расшифровку ССЗБ можно?))
« Последнее редактирование: Февраль 23, 2012, 13:49 от lolbla2 » Записан
mutineer
Гость
« Ответ #14 : Февраль 23, 2012, 13:48 »

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


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