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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Интересная ситуация при подключении *.dll динамически  (Прочитано 4518 раз)
Ascet
Гость
« : Январь 14, 2015, 07:19 »

Прошу помощи, ибо не совсем опытный программист... Непонимающий

Основная ситуация:
Базовый класс и другие требуемые для работы классы описаны в одном проекте. Он компилируется с формированием *.dll. Другие проекты подключают эту длл-ку статически и классы, описанные в этих проектах наследуются от базового класса и собираются опять же с получением *.dll файла, который уже должен подгружаться в моём приложении.

Проблема:

При попытке подключить эту dll, к которой статически подключена другая dll QLibrary напрочь отказывается эту длл-ку подгружать.
-----------------------------------------------------------------------------
Локализовал проблему до таких простых проектов:

TestBaseClass.pro
Код:
TARGET = TestBaseClass

TEMPLATE = lib
CONFIG += dll
DESTDIR = ../include/dll/

SOURCES += main.cpp\
        testbaseclass.cpp

HEADERS  += testbaseclass.h

FORMS    += testbaseclass.ui

TestBaseClass.h
Код:
#ifndef TESTBASECLASS_H
#define TESTBASECLASS_H

class TestBaseClass
{
    public:
        TestBaseClass();
        ~TestBaseClass();
};

#endif // TESTBASECLASS_H

TestBaseClass.cpp
Код:
#include "testbaseclass.h"
#include "ui_testbaseclass.h"

TestBaseClass::TestBaseClass()
{
}

TestBaseClass::~TestBaseClass()
{
}
-----------------------------------------------------------------
Теперь создаём второй проект, где будет дочерний класс

TestWidget2.pro
Код:
TARGET = TestWidget2
TEMPLATE = lib
CONFIG += dll
DESTDIR = ../include/dll/

SOURCES += main.cpp\
        testwidget2.cpp

HEADERS  += testwidget2.h

FORMS    += testwidget2.ui

win32: LIBS += -L$$PWD/../include/dll/ -lTestBaseClass

INCLUDEPATH += $$PWD/../TestBaseClass
DEPENDPATH += $$PWD/../TestBaseClass

TestWidget2.h
Код:
#ifndef TESTWIDGET2_H
#define TESTWIDGET2_H

#include "testbaseclass.h"

class TestWidget2 : public TestBaseClass
{
    public:
        TestWidget2();
        ~TestWidget2();
};

extern "C" __declspec(dllexport)
{
    TestBaseClass* createClass()
    {
        return new TestWidget2;
    }
}

#endif // TESTWIDGET2_H

TestWidget2.cpp
Код:
#include "testwidget2.h"
#include "ui_testwidget2.h"

TestWidget2::TestWidget2() :
    TestBaseClass()
{
}

TestWidget2::~TestWidget2()
{
}

Участок кода, которым пытаюсь подцепить библиотеку:
Код:
QLibrary* lib = new QLibrary(file_name);
    if(!lib->load())
    {
        ui->textEdit->append(lib->errorString());
    }
    delete lib;

Текст выдаваемой ошибки:
Цитировать
Cannot load library D:\Work\ARM\include\dll\TestWidget2: Не найден указанный модуль.

Версия Qt 5.4.0, ОС Windows 7 32-бита, При компиляции всех проектов никаких ошибок не возникает, но всё равно библиотека не подцепляется.
Я не очень опытный программист, потому многого не понимаю в функционировании динамических библиотек и в данной ситуации немного впал в ступор.. Что я делаю не так?

PS: В силу специфики задачи QPluginLoader не подходит из-за того, что придется описывать интерфейсы, которые в дальнейшей работе придется часто редактировать и в каждом подгружаемом модуле описывать одни и те же методы.. Так что думаю в моей ситуации самым верным будет использовать именно QLibrary, но столкнулся и вышеописанной проблемой...
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #1 : Январь 14, 2015, 09:31 »

Попробуйте в качестве file_name использовать не "D:\Work\ARM\include\dll\TestWidget2", а "D:\Work\ARM\include\dll\TestWidget2.dll".
« Последнее редактирование: Январь 14, 2015, 14:33 от xokc » Записан
Ascet
Гость
« Ответ #2 : Январь 14, 2015, 11:20 »

file_name в данном случае берется из вот такой записи

Код:
QString file_name = QFileDialog::getOpenFileName(this, "Open dll", "../ARM/", "DLL (*.dll)");
    if (file_name.isEmpty())
        return;

а строка
Цитировать
Cannot load library D:\Work\ARM\include\dll\TestWidget2: Не найден указанный модуль.
возвращается из
Код:
lib->errorString()

Поясню, что ошибки в адрессе нет, другие dll, которые не тянут за собой статически подключенных других длл подключаются на Ура.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Январь 14, 2015, 11:53 »

file_name в данном случае берется из вот такой записи
Напрасно "дебатируете". Посоветовали проверить полное имя/путь - это разумно. Вбейте его руками и убедитесь - быстрее и дешевле выйдет.

Поясню, что ошибки в адрессе нет, другие dll, которые не тянут за собой статически подключенных других длл подключаются на Ура.
"статически подключенных dll" - неудачный термин, трудно понять о чем Вы. Наверное имели ввиду dll загружаемые автоматом (т.е. без них приложение не запускается, а зависимая dll не грузится), в Вындоуз называются как-то load-time или implicit.

Для начала посмотрите через DependencyWalker. Попробуйте тупо LoadLibrary - она скажет чего не находит. Попробуйте прилинковать "базовую" - тоже загрузчик скажет в чем дело. 
Записан
Ascet
Гость
« Ответ #4 : Январь 14, 2015, 12:06 »

Просто в оригинальном коде адрес файла берется другим образом и он был первым на что я грешил. Все возможные вариации были испробованы. То, что дело не в адресе я уже убедился и само собой руками прописанный адрес не берется. Первоначально адресс был без *.dll согласно документации Qt, но как показала практика удачно подгружаются как библиотеки без указания формата, так и с ним. Ну это просто из разряда интересных наблюдений.

Цитировать
"статически подключенных dll" - неудачный термин, трудно понять о чем Вы. Наверное имели ввиду dll загружаемые автоматом (т.е. без них приложение не запускается, а зависимая dll не грузится), в Вындоуз называются как-то load-time или implicit.

Для начала посмотрите через DependencyWalker. Попробуйте тупо LoadLibrary - она скажет чего не находит. Попробуйте прилинковать "базовую" - тоже загрузчик скажет в чем дело.

Сейчас попробую спасибо)
Записан
Ascet
Гость
« Ответ #5 : Январь 14, 2015, 13:15 »

Господа, Решение найдено! Улыбающийся
Всё оказалось намного проще.
В про файле приложения, которым подцепляем длл дочернего класса нужно тоже прописать подцепление длл родительского класса.
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #6 : Январь 14, 2015, 14:33 »

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


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