Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Формы в Dll

362
03 декабря 2002 года
_kolyan
339 / / 03.12.2002
Такая проблема
Когда создаешь DLL в которой содержатся формы,
программа для каждой формы (даже для тех которые не в DLL) начинает создавать отдельную кнопку на панели задач.
Кнопка не создается только если форма сделана как bsToolWindow
Кто-нибуть подскажите что это
Буду очень благодарен
317
03 декабря 2002 года
Relax
573 / / 20.09.2000
насколько я знаю, такой эффект возникает когда и экзешник и длл собраны со всеми библиотеками внутри, то есть с отключенными в опциях проекта флажками use dynamic RTL и build with runtime packages...
362
03 декабря 2002 года
_kolyan
339 / / 03.12.2002
Цитата:
Originally posted by Relax
насколько я знаю, такой эффект возникает когда и экзешник и длл собраны со всеми библиотеками внутри, то есть с отключенными в опциях проекта флажками use dynamic RTL и build with runtime packages...



Все библиотеки лежат снаружи то есть Use dynamic RTL стоит, все Runtime packages тоже внешние, а то если все их встраивать, программа получится больше чем все packages'ы вместе взятые (проект довольно сложый)

317
03 декабря 2002 года
Relax
573 / / 20.09.2000
у меня вообще-то именно в этом пободная проблема была - после того как сделал библиотеки внешними - все получилось...
358
03 декабря 2002 года
moonmike
423 / / 18.10.2002
Q: Я разделил свою программу на основной Exe и Dll. после этого все стало
глючить.
(Возможные симптомы: программа отображается на линейке 2 раза, появляются
загадочные сообщения типа "Cannot assign TFont to TFont", базы данных спрашивают
пароль 2 раза(один раз для dll и один раз для exe), происходят загадочные Access
Violation )

Вы неправильно скомпоновали вашу dll. Для того чтобы все заработало нужно
скомпилить и Exe и Dll c dynamic rtl и runtime packages. Проверьте так же что
все Packages перечислены в списке RP. Т.е. может быть такая ситуация,
что RP включены, но какой нибудь из них в списке пропущен и используется
статически.

Многим людям лень искать какие dll нужны поэтому они все линкуют
в свои exe и dll. Я категорически рекомендую не делать этого.
Уже если вы разделили прогу на exe dll то используйте все остальное
тоже в dll

Несколько причин последовать этому совету:

Причина 1.
Вы все наверняка работали с чужими dll. Хотя бы вызывая функции Windows.
Вы обратили внимание что все строки в них передаются с помощью char*.
Кроме того когда вы например вызываете функцию GetComputerName,
то она не просто возвращает строку, а заставляет вас передать указатель
на буфер и его длину. Это сделано для того чтобы не было таких вещей
чтобы память выделялась в одном модуле а стиралась в другом. Потому как
это некорректно.
В каждом модуле есть такая штука как memory manager которая
выделяет память, освобождает ее и ведет список свободных и занятых блоков.
Так вот когда у вас exe и dll скомпилены без dynamic rtl то получается что у вас
2 разных memory manager-а. Как вы думаете что будет если вы попросили у одного
из них память, а потом попросили другого его стереть?
Я думаю ничего хорошего не получится. Можно конечно дать совет не делать
так. Но учтите что при передаче AnsiString в качестве параметра память
выделяется в вызывающей функции, а уничтожается в вызваной.
Таким образом получается, что нельзя вызывать из dll функции с
параметром AnsiString.

Как это лечится.
1) Достаточно включить use dynamic rtl и у вас получится один менеджер
памяти в специальной dll borlndmm.dll
2) Можно не включать, а сделать как написано в большом комментарии в начале
новосозданной dll. Там рекомендуют включить в проект MEMMGR.LIB. Но в этом
случае все равно будет использоваться borlndmm.dll.
Легче сделать как сказано в пункте 1.

Причина 2.
Вы знаете о существовании глобальных переменных Application, Session и т.п?
А знаете где они объявлены? Соответственно в Forms и Dbtables. А догадываетесь
что будет если подключить эти unit-ы статистически к exe и dll? Правильно у вас
будет по 2 копии этих переменных, одна в одном модуле другая в другом.
Именно из-за этого появляются такие эффекты как двойное название приложения
в линейке задач (чего вы удивляетесь, у вас на самом деле 2 приложения) и
то что пароли к базе данных(имеется ввиду BDE)спрашиваются 2 раза
(у вас 2 сессии, один раз введите пароль для одной и один для другой.
Кстати соединений с БД у вас тоже будет 2).

Как это лечится.
Ну например в случае раздвоения на линейке задач можно передать в dll
Application->Handle из exe и присвоить его местному Application->Handle.
Для Session это наверное тоже как нибудь лечится. Но самый простой
путь это включить Runtime Packages. Тогда у вас будет только одна
копия переменных в отдельном Bpl

Причина 3.
Вы не задумывались как работают операции динамического определения типа.
dynamic_cast в C++ и is/as в Pascal? Они сравнивают указатель на виртуальную
таблицу. Что будет если один и тот же компонент есть в 2 модулях? Правильно,
у него будет 2 виртуальные таблицы. Что будут делать операторы определения
типа когда определяют тип компонента из другого модуля пытаясь сравнить его
vptr с vptr который должен быть в этом модуле? Правильно, они скажут что это
разные компоненты. Отсюда всякие извраты типа Cannot assign TFont to TFont.
Кроме того например Toolbar2000 будучи пристыкован статически не опознает
свои собственные Toolbar-ы из другого модуля и отказывается их пристыковывать.
Есть информация что IBX в таком состоянии просто глючит. Некоторые компоненты
все таки ведут себя вполне прилично, но вы готовы рисковать работоспособностью
программы чтобы выяснить что тот компонент который вы используете именно такой?

Как лечить. Те классы которые не наследуются от TObject определяется
правильно ( Magic! ). С наследниками TObject сделать ничего нельзя.
Единственный выход это включить Runtime Packages.

Причина 4.
При всем этом суммарный объем кода увеличивается т.к. один и тот же код
содержится и в dll и в exe.

Мораль.
Либо не используйте dll вообще либо делайте их с dynamic rtl и
runtime packages. Обычно эти опции отключают чтобы не искать какие
dll и bpl еще нужны. Но поверьте это ничто по сравнению с тем количеством
проблем которые вас ожидают если вы не воспользуетесь этим советом.
362
03 декабря 2002 года
_kolyan
339 / / 03.12.2002
Большое спасибо за скопированный вами текст, было очень интересно, хотя некоторые вещи я уже знал, и про memory manager и большой комментарий в начале DLLMain тоже читал, и про передачу AnsiString.
Я использую динамические библиотеки и runtime packages то есть не линкую их внутрь проекта тем не менее проблема остается
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог