Russian Qt Forum

Qt => Уроки и статьи => Тема начата: Eugene Efremov от Декабрь 20, 2008, 19:23



Название: Урок: Создание динамических библиотек
Отправлено: Eugene Efremov от Декабрь 20, 2008, 19:23
Создание динамических библиотек

Вступление

Тема динамических библиотек, казалось бы, раскрыта 42 главе фундаментального труда Шлее. Однако, при ближайшем рассмотрении выясняется, что раскрыта она, прямо скажем, недостаточно. В приведенном примере Шлее ограничивается рассмотрением создания и использования DLL, содержащей только функции, но не классы. После чего сразу переходит к рассмотрению плагинов.

Между тем, при создании динамических библиотек, содержащих классы, возникают некоторые тонкости, которые необходимо учитывать. Об этом и пойдет речь в данном howto.

При описании я буду предполагать, что читатель в общих чертах знаком с основами Qt, и у него не возникнет вопросов типа «а что такое QVBoxLayout. Так что я не буду описывать текст исходников примера (он сам по себе весьма прост), а сосредоточусь непосредственно на особенностях, характерных для DLL. Если с пониманием примера все же возникнут трудности — рекомендую сперва прочитать того же Шлее, а уже потом обратится к этому тексту.

И еще — здесь рассматривается только явная компоновка приложения и библиотеки. Если необходимо подгрузить класс динамически — лучше оформить его как плагин. В противном случае вас ждут большие проблемы...


1.Библиотека

Лежит в директории src/dll.

Библиотека содержит простейший виджет, производный от QLabel. Им можно пользоваться точно также, как любым другим виджетом Qt: добавлять в свои виджеты, использовать слоты/сигналы, создавать производные классы и т.д.

Отличие от обычного Qt приложения сосредоточены, в основном, в двух файлах: ddll.h и dll.pro.

ddll.h:
Код
C++ (Qt)
#ifndef D_DLL
#define D_DLL
#include <QtGlobal>
 
#ifdef D_SHARED_LIB
#define D_SHARED Q_DECL_EXPORT
#else
#define D_SHARED Q_DECL_IMPORT
#endif
 
#endif
 

Вообще говоря, без этого файла можно обойтись. Если пользоваться нормальным компилятором. Но, помимо нормальных компиляторов, существуют еще компиляторы от microsoft. И в них, по слухам, требуется подобное извращение.

Что здесь написано. Q_DECL_EXPORT и Q_DECL_IMPORT — это два недокументированных (пока?) макроса, которые введены разработчиками Qt специально, чтобы обойти эти грабли в MSVS. Первый из них требуется писать перед объявлением класса в DLL, второй — в приложениях, которые этот DLL используют. Во всех остальных компиляторах они равны пустой строке.

Соответственно, перед всеми классами в нашей библиотеке мы должны проставить наш макрос D_SHARED:
Код
C++ (Qt)
#include <QLabel>
#include "ddll.h"
 
class D_SHARED DLabel : public QLabel
{
Q_OBJECT
....
 


На этом отличия исходного кода кончаются. Главные различия касаются файла проекта:

dll.pro:
Код
TEMPLATE = lib
CONFIG += shared
 
# in
VERSION = 1.0.0
DEFINES += D_SHARED_LIB
SOURCES = dlabel.cpp
HEADERS = dlabel.h ddll.h
 
# out
TARGET = dlabel
DLLDESTDIR = ../../bin
DESTDIR = ../../lib
 

Полагаю, TEMPLATE и CONFIG в комментариях не нуждаются. На некоторых других вещах стоит остановится подробнее.

DEFINES — определяем макрос D_SHARED_LIB, который используется в ddll.h (см. выше).
DESTDIR и DLLDESTDIR — мы помещаем получившуюся библиотеку в lib. Но само приложение у нас будет находится в bin, поэтому мы копируем DLL туда.
VERSION — а вот здесь нам необходимо небольшое лирическое отступление.

Существует такая вещь, как бинарная совместимость. Если кратко — мы создаем некоторую структуру, помещаем ее в DLL. Потом наши приложения этот DLL юзают. А потом мы ее изменяем. И перезаписываем DLL поверх старого. А приложения обращаются к ней по старым адресам... Результат, думаю, ясен.
Так вот, это называется — отсутствие бинарной совместимости. В просторечии — dll hell.

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

Однако, вернемся к нашим баранам. Увидев VERSION, qmake во-первых, принимает необходимые меры, чтобы эта версия прописалась вo внутренних свойствах DLL, а, во-вторых — приписывает ее старший номер к имени создаваемого DLL. Т.е. в нашем примере это будет dlabel1.dll. Соответственно, если мы изменим интерфейс нашей библиотеки до полной несовместимости, для предотвращения использования ее старыми приложениями мы должны будем просто сменить VERSION на 2.0.0. И тогда новые версии будут использовать dlabel2.dll, старые — dlabel1.dll.


2.Приложение

Лежит в директории src/main.

Как я уже писал выше — мы можем использовать наш виджет точно также, как любой другой. Единственные отличия — в pro-файле.

main.pro:
Код
TEMPLATE = app
CONFIG += qt warn_on
 
#in
DEPENDPATH += ../dll
INCLUDEPATH += ../dll
LIBS += -L../../lib -ldlabel
HEADERS = dlcat.h
SOURCES = dlcat.cpp dmain.cpp
RESOURCES = longcat.qrc
 
#out
DESTDIR = ../../bin
TARGET = longcat
 

Остановимся на этих отличиях подробнее.

INCLUDEPATH — указываем путь к хидерам библиотеки.
DEPENDPATH — объясняем qmake, что хидеры библиотеки необходимо учитывать при построении зависимостей.
LIBS — подключаем библиотеку. При этом путь и сам библиотека указывается отдельно и в самом общем виде (без расширений и т.п.). В такой форме это будет правильно обработано для любого компилятора. VERSION у библиотеки должен быть указан, иначе это не сработает. При наличии нескольких версий будет выбрана последняя.


3. Возможные грабли

При использовании динамической линковки следует помнить о некоторых общих вещах, которые необходимо учитывать во избежание ошибок. Впрочем, при нормальной работе Qt, в большинстве случаев, сама заботится о том, чтобы сделать «нарушение правил» достаточно сложным...
Итак:

1. Пользуйтесь для сборки библиотеки и приложения одним и тем же компилятором.

Разные компиляторы по-разному кодируют в объектном коде имена функций, классов и т.д. Более того, могут отличаться и смещения полей внутри класса. По этому попытка подключить dll, собранный в другом компиляторе, скорее всего, увенчается успехом лишь в том случае, если все ф-ции отмечены как extern "C" и смещения структур выравнены принудительно. Для классов это, разумеется, не подходит.

Как ни трудно понять, при самостоятельной разработке библиотеки эта проблема вряд ли возникнет. А вот если мы имеем чужой dll и закрытый код... Тем, кто попал в такую ситуацию, остается только посочувствовать.


2. ...И одними и теми же опциями командной строки — в части, влияющей на свойства генерируемого кода.

Имеются в виду, прежде всего, опции, включающие поддержку исключений, RTTI, управляющие отладочной информацией и т. п. Как ни трудно догадаться, если в один модуль скомпилирован с поддержкой RTTI, другой — без, то при использовании этого самого RTTI программу ждут большие неприятности. То же касается и отладки (там разные версии стандартных библиотек — см. ниже).

В Qt об опциях командной строки компилятора заботится qmake, так что в обычной ситуации эта проблема возникать не должна. Иными словами — если не делать явных глупостей, вроде смешения debug и release в одну кучу, то этого и не произойдет.


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

Если CRT (http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B0%D0%BD%D0%B4%D0%B0%D1%80%D1%82%D0%BD%D0%B0%D1%8F_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B0_%D0%A1%D0%B8) скомпонована статически, то ресурс (например — память), выделенный в рамках одного модуля, невозможно корректно освободить в рамках другого: каждый из них будет оперировать со своим адресным пространством и своими копиями внутренних структур, обеспечивающих нормальный доступ к ресурсам. Кроме того, разумеется, нужно следить, чтобы во всех модулях использовалась CRT одной и той же версии.

В Qt все низкоуровневые вызовы инкапсулированы в рамках модуля QtCore. Так что помнить это правило нужно лишь при низкоуровневой работе с вещами, для которых Qt не предоставляет удовлетворительной поддержки. Впрочем, такую работу нужно инкапсулировать в любом случае. В штатных же случаях — просто пользуйтесь стандартными средствами библиотеки — и будет вам счастье :).

Разумеется, при этом саму Qt необходимо линковать динамически. Вообще, динамическую и статическую линковку в одну кучу мешать не следует — многих проблем удастся избежать.


И еще, касательно данного примера. Следует иметь в виду, что он писался в предположении, что библиотека будет линковаться только динамически. Для для случая статической линковки макросы Q_DECL_IMPORT/EXPORT следует убрать. Как средствами qmake отличить статическую линковку от динамической и обеспечить включение/выключение нужных макросов — продемонстрировано ниже по треду (http://www.prog.org.ru/index.php?topic=8259.msg44623#msg44623) в письме от pastor, на модификации моего примера. За что ему отдельное спасибо.

Собственно, на этом всё. Enjoy! :)


Проверено
  • под Windows 2003 в Qt 4.4.1, в компиляторе mingw, gcc version  3.4.5
  • под Windows XP x64 в Qt 4.4.3, в MSVS 2008
  • под openSuse 11 в Qt 4.4.3, в gcc version 4.3.1 20080507
За последние 2 варианта — спасибо pastor!


Название: Re: HowTo: Создание динамических библиотек
Отправлено: pastor от Декабрь 20, 2008, 20:20
Да, действительно, __dllimport (Q_DECL_IMPORT) и __dllexport (Q_DECL_EXPORT) это приблуда MS Visual Studio. Если использовать другой компилятор, отличный от MS Visual Studio, то без этого можно обойтись. Но это ещё не все, что касается этих макросов и MS Visual Studio. Если разрабатываемую вами библиотеку сделать статической, то приложение, использующее её, линковатся не будет. Причина в том, что при статической линковке эти макросы также не нужны.

Я немного модифицировал код Eugene Efremov.

Проверено: Windows XP x64, Qt 4.4.3, MSVS 2008
                  openSuse 11, Qt 4.4.3, gcc version 4.3.1 20080507


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Rcus от Декабрь 20, 2008, 20:34
На самом деле MinGW тоже поддерживает эти директивы (другое дело что если их не указывать msvc не будет экспортировать символы вообще, а MinGW экспортирует все указанные в хедерах).

И еще не хватает части про несовместимость name mangling, проблемы с dynamic_cast и crt. А так описываются почти все грабли :)


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Eugene Efremov от Декабрь 22, 2008, 17:13
И еще не хватает части про несовместимость name mangling, проблемы с dynamic_cast и crt. А так описываются почти все грабли :)

Проблемы с dynamic_cast — имеется в виду, что для его нормальной работы оно оба модуля должны быть скомпилированы с поддержкой RTTI? Или там еще какие-то грабли есть, про которые я не знаю?

В общем, секцию с граблями я добавил, если про dynamic_cast нужно что-то еще — поправлю...


Я немного модифицировал код Eugene Efremov.

Спасибо.
Я указал в конце, что рассматривался только случай динамической линковки, а если нужно еще и статическую — см. ниже. И дал ссылку на этот новый пример.


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Rcus от Декабрь 22, 2008, 19:09
Проблемы с dynamic_cast — имеется в виду, что для его нормальной работы оно оба модуля должны быть скомпилированы с поддержкой RTTI? Или там еще какие-то грабли есть, про которые я не знаю?

В общем, секцию с граблями я добавил, если про dynamic_cast нужно что-то еще — поправлю...

если мы создаем в одном исполняемом модуле некоторый объект и передаем указатель на его в динамическую библиотеку, то dynamic_cast будет выдавать 0. Это связано с особенностью реализации rtti. Отчасти эту проблему решает qobject_cast, но работает только для потомков QObject.
Грабли crt заключены в том, что оба модуля должны линковаться с одной версией crt (например релизная и отладочная версии несовместимы)


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Eugene Efremov от Декабрь 22, 2008, 21:33
если мы создаем в одном исполняемом модуле некоторый объект и передаем указатель на его в динамическую библиотеку, то dynamic_cast будет выдавать 0. Это связано с особенностью реализации rtti. Отчасти эту проблему решает qobject_cast, но работает только для потомков QObject.

Ммм... У меня в gcc этот баг не получается воспроизвести. Все dynamic_cast отлично работают и там, и там. Можно пример кода?

Или это еще один личный глюк MSVS?

Грабли crt заключены в том, что оба модуля должны линковаться с одной версией crt (например релизная и отладочная версии несовместимы)

Т.е., фактически попадает под то, что у меня описано в п.2. Добавил там про отладку.


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Rcus от Декабрь 22, 2008, 22:06
На самом деле это не баг, а особенность механизма линковки. Демо проект прикреплен,
Код:
main@rcuhome:~$ g++ --version
g++ (Ubuntu 4.3.2-1ubuntu11) 4.3.2


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Eugene Efremov от Декабрь 22, 2008, 22:40
На самом деле это не баг, а особенность механизма линковки. Демо проект прикреплен,
Код:
main@rcuhome:~$ g++ --version
g++ (Ubuntu 4.3.2-1ubuntu11) 4.3.2

Ну и? У меня (windows 2003, g++ 3.4.5) все работает:
Код:
Dynamic? Foo::test, upcast ? = 0
Dynamic? Bar::test, upcast ? = 2293584

Хотя, если учесть, что там мешается в одну кучу статическая и динамическая линковка — меня это очень удивляет. При таком раскладе действительно странно, что оно работает. Если заменить в foobar.pro static на shared — оно под linux'ом заработает?
Если да — dynamic_cast тут несколько сбоку...

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


Название: Re: HowTo: Создание динамических библиотек
Отправлено: lex_newton от Август 05, 2009, 10:04
Собственно, хочу рассказать о граблях ;)
Windows XP SP3, g++ (GCC) 3.4.2 (mingw-special), QT 4.4.3

Создаю динамическую библиотеку в которой находится класс унаследованный от QWidget и имеет макрос Q_OBJECT
Код:
class MyClass : public QWidget
{
Q_OBJECT
public:
    MyClass( QWidget* parent = 0 );
    ...
}

Собираю динамическую библиотеку (все собирается без ошибок и т.п.)
Код:
CONFIG += shared

И в главной программе использую MyClass.
В чем грабли?
Если использовать MyClass то ничего особенного не происходит. все работает прекрассно.
НО! Если попытаться в главной программе сделать нечто подобное, то возникает ошибка 0xc0000005 при запуске программы
Код:
class MyClass2 : public MyClass
{
Q_OBJECT
public:
    MyClass2( QWidget* parent = 0 );
}

Причем, если закомментировать Q_OBJECT то программа перестает вылетать.

Как оказалось, дело в том, что под windows даже используя gcc необходимо указывать Q_DECL_EXPORT Q_DECL_IMPORT.
И VS тут не при чем, это фишка платформы win32.

+ если мы хотим экспортировать не класс, а функцию, поступаем тем же самым способом. пишем перед прототипом функции соотвествующие макросы.



Название: Re: HowTo: Создание динамических библиотек
Отправлено: polyakovp84 от Сентябрь 29, 2009, 17:38
Разбираясь с данным примером понял, что библиотека загружается сразу при запуске программы.

А как сделать чтобы при выполнении некого условия библиотека загружалась динамически, затем содавался класс для последующей работы с ним?
Если можно простой работающий пример.
Заранее благодарен.


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Rcus от Сентябрь 29, 2009, 17:43
"Plug & Paint Example"


Название: Re: HowTo: Создание динамических библиотек
Отправлено: SASA от Октябрь 01, 2009, 15:37
Есть проблема с qobject_cast.
Если класс описан в dll и создан там же, то в app попытка привести указатель к этому классу даёт ноль.
Ответ сказали искать здесь
http://www.qtcentre.org/forum/f-qt-programming-2/t-casting-result-of-qwidgetstack-currentwidget-5037.html (http://www.qtcentre.org/forum/f-qt-programming-2/t-casting-result-of-qwidgetstack-currentwidget-5037.html)
Но я чё-то не понял и проблему решить не смог. Может есть у кого какие мысли.
З.Ы. Билбиотека загружается динамически - плагин.


Название: Re: HowTo: Создание динамических библиотек
Отправлено: UVV от Октябрь 01, 2009, 16:10
Там в принципе описано решение, использовать третью библиотеку и линковаться с ней.
Но у меня прокатило просто dynamic_cast =)


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Elfet от Апрель 06, 2010, 18:20
Приветствую!

У меня возникла такая проблема с dll, не знаю в чём дело. Пожалуйста, помогите!

Есть два проекта: один интерфейс, другой библиотека dll на чистом C++

Всё собираю в QtSDK (Qt Creator + minGW).

Одно время было всё хорошо, а вот недавно по непонятной мне причине появились глюкт с dll. Нажимаю пересобрать библиотеку, затем пересобрать интерфейс, запускаю - вроде бы всё хорошо, но выполняется совсем не тот код (видно по тому что отображается на интерфейсе)

Однако если я нажимаю F5 (отладка) то всё запускается нормально и выполняется нормально.

В чём тут дело?  ???

Может быть я что-то неправильно настроил?
SmartFlow.pro:
Цитировать
...
# SmartFlowLib
DEPENDPATH += ../SmartFlowLib/Source
INCLUDEPATH += ../SmartFlowLib/Source
LIBS += ./debug/smartflowlib1.dll
...


SmartFlowLib.pro
Цитировать
QT -= gui
TEMPLATE = lib
CONFIG += shared

TARGET = smartflowlib
DESTDIR = ../SmartFlow/debug

VERSION = 1.0.0.1

Весь код можно найти тут: http://code.google.com/p/smart-flow/source/browse/#svn/trunk

Заранее спасибо!


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Amigo_sa от Апрель 06, 2010, 18:22
у нас такое было, когда в папке с объектными файлами случайно оказывались одноименные. проверьте пути, скорее всего просто либа собирается из старых объектников


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Elfet от Апрель 06, 2010, 18:34
Да я вроде бы всё очистил. Даже папки все удалил.  И полностью пересобрал всё.

Ещё я заметил что запуская несколько раз подряд свою программу - ошибки разные появляются  :-\


Название: Re: HowTo: Создание динамических библиотек
Отправлено: Elfet от Апрель 06, 2010, 19:16
И вот ещё что не понятно. Если запуская не через Qt (Ctrl+R) А захожу в папку и запускаю файл SmartFlow.exe - всё работает нормально (Остальный Qt***.dll лежат в этой же папке)


Название: Re: Урок: Создание динамических библиотек
Отправлено: serg_hd от Июнь 23, 2010, 13:03
Непонятны слова
И еще — здесь рассматривается только явная компоновка приложения и библиотеки. Если необходимо подгрузить класс динамически — лучше оформить его как плагин. В противном случае вас ждут большие проблемы...
А тут разве классы подгружаются не динамически? dll же.
И чем отличается явная компоновка от динамической подгрузки - не описано?


Название: Re: Урок: Создание динамических библиотек
Отправлено: Igors от Июнь 23, 2010, 13:54
А тут разве классы подгружаются не динамически? dll же.
И чем отличается явная компоновка от динамической подгрузки - не описано?
Здесь имеется ввиду 2 подхода

1) dll загружается при старте приложения (в заголовке exe указано какие dll необходимы). Если ОС не сможет их найти/ загрузить - exe не запустится. Ф-ции dll доступны в течение всей жизни exe

2) Приложение стартует без dll, а затем само (используя ф-ции OC) загружает dll (может и выгружать). Ф-ции dll обычно запрашиваются через GetProcAddress (Вындоуз)


Название: Re: Урок: Создание динамических библиотек
Отправлено: andrey2033 от Июль 05, 2010, 13:26
Доброго времени суток!
У меня возникла проблема с friend-функциями класса в моей библиотеке. При их наличии компилятор выдаёт ошибку undefined reference... к этим функциям...
Без них всё работает. И отсюда вопрос: в dll нельзя пользоваться friend-функциями?


Название: Re: Урок: Создание динамических библиотек
Отправлено: xintrea от Июль 10, 2010, 22:44
Автор этой статьи удалил свой аккаунт на форуме. Так что он, наверно не ответит. Лучше задать этот  вопрос в другом разделе, например в "Общих вопросах" http://www.prog.org.ru/board_50_0.html (http://www.prog.org.ru/board_50_0.html).


Название: Re: Урок: Создание динамических библиотек
Отправлено: andrey2033 от Июль 14, 2010, 09:40
Автор этой статьи удалил свой аккаунт на форуме. Так что он, наверно не ответит. Лучше задать этот  вопрос в другом разделе, например в "Общих вопросах" http://www.prog.org.ru/board_50_0.html (http://www.prog.org.ru/board_50_0.html).

Спасибо!


Название: Re: Урок: Создание динамических библиотек
Отправлено: voral от Март 03, 2011, 12:20
В последнем абзаце слово повторяется....
И еще, касательно данного примера. Следует иметь в виду, что он писался в предположении, что библиотека будет линковаться только динамически. Для для случая статической линковки макросы Q_DECL_IMPORT/EXPORT следует убрать. Как средствами qmake отличить статическую линковку от динамической и обеспечить включение/выключение нужных макросов — продемонстрировано ниже по треду (http://www.prog.org.ru/index.php?topic=8259.msg44623#msg44623) в письме от pastor, на модификации моего примера. За что ему отдельное спасибо.


Название: Re: Урок: Создание динамических библиотек
Отправлено: raus от Июнь 22, 2012, 12:40
Здравствуйте. Могу ли я dllку Qt использовать в mfc проекте?


Название: Re: Урок: Создание динамических библиотек
Отправлено: Bepec от Июнь 22, 2012, 16:43
Если наружу выставить за. ой, интерфейс на С++, то да. Однако кажется, что сигнал-слотовые соединения не будут работать, если не запущен QApplication.

Есть вроде и обход этих ограничений :)


Название: Re: Урок: Создание динамических библиотек
Отправлено: raus от Июнь 22, 2012, 17:23
Если наружу выставить за. ой, интерфейс на С++, то да. Однако кажется, что сигнал-слотовые соединения не будут работать, если не запущен QApplication.

ну вроде выставил я интерфес C++? а в проекти dllки экземпляр QApplication вот так создаю:
Код:
	int argc = 1;
QApplication app(argc, NULL);
           ..............
           ..............
           ..............
           app.exec();

dllка вроде создалась, но что-то не могу ее прикрутить к проекту



Название: Re: Урок: Создание динамических библиотек
Отправлено: mutineer от Июнь 22, 2012, 17:26
ты же в курсе, что app.exec() это цикл бесконечный?


Название: Re: Урок: Создание динамических библиотек
Отправлено: raus от Июнь 22, 2012, 18:04
ты же в курсе, что app.exec() это цикл бесконечный?
ну так с цикла можно будет выйти, если главный виджет разрушится..


Название: Re: Урок: Создание динамических библиотек
Отправлено: mutineer от Июнь 22, 2012, 18:05
Я имел в виду что вызов библиотечного метода с таким содержимым заблокирует вызывающего


Название: Re: Урок: Создание динамических библиотек
Отправлено: raus от Июнь 23, 2012, 14:55
Я имел в виду что вызов библиотечного метода с таким содержимым заблокирует вызывающего
ну мне этэ, наверно, не страшно..


Название: Re: Урок: Создание динамических библиотек
Отправлено: raus от Июнь 23, 2012, 15:03
Подскажите пожалуйста.
я создал dll в visual studio, но почему-то не могу вызвать метод из нее...еще создавал libку, метод вроде виден, но при сборке куча ошибок, ну это, вроде как и понятно, тк в ней Qt ...думаю с dllкой должно быть все норм..но вот не находится мой метод ???


Название: Re: Урок: Создание динамических библиотек
Отправлено: xintrea от Июнь 24, 2012, 21:53
Подскажите пожалуйста.
я создал dll в visual studio, но почему-то не могу вызвать метод из нее...еще создавал libку, метод вроде виден, но при сборке куча ошибок, ну это, вроде как и понятно, тк в ней Qt ...думаю с dllкой должно быть все норм..но вот не находится мой метод ???

Последовательность действий:

1. Выучить русский язык, его правила грамматики и пунктуации. Это требуется сделать чтобы люди могли понять тебя.

2. Начать читать документацию о проектировании dll и вообще о разделяемых библиотеках.

3. Понять что телепаты обитают на других форумах, и какие у тебя ошибки тут никто не знает.


Название: Re: Урок: Создание динамических библиотек
Отправлено: raus от Июнь 25, 2012, 11:30

2. Начать читать документацию о проектировании dll и вообще о разделяемых библиотеках.


вот этот пункт помог. спасибо ;)