Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.10.30;
Скачать: CL | DM;

Вниз

Форма в dll. Пытаюсь разобраться   Найти похожие ветки 

 
EgorovAlex ©   (2010-03-29 13:13) [0]

Есть такой код библиотеки:


library pDll;

uses
 Windows, SysUtils, Classes, Forms,
 uDll;

{$R *.res}

procedure Show(App: TApplication); stdcall;
var
 DllApp: TApplication;
begin
 DllApp := Application;
 Application := App;
 with TForm.Create(Application) do
 try
   ShowModal;
 finally
   Free;
 end;
 Application := DllApp;
end;

exports
 Show;

begin
end.


Вызываю так:
procedure TFormTest.btnTestDllClick(Sender: TObject);
var
 hLib: THandle;
 Show: procedure(App: TApplication); stdcall;
begin
 @Show := nil;
 hLib := LoadLibrary("pDll.dll");
 if (hLib > 0) then
 try
   @Show := GetProcAddress(hLib, "Show");
   if (@Show <> nil) then
     Show(Application);
 finally
   FreeLibrary(hLib);
 end;
end;


Первый вызов проходит удачно, а после второго клика на баттоне выскакивает аксесс виолейшн. В чём может быть дело? Форма в dll пустая.

Если процедуру создания формы заменить на:

procedure Show(App: TApplication); stdcall;
begin
 with TForm.Create(App) do
 try
   ShowModal;
 finally
   Free;
 end;
end;


То форма создаётся нормально много раз, только форма теперь не по центру главной формы создаётся, а в центре экрана, а это не устраивает (у формы стоит Position := poMainFormCenter)


 
Application   (2010-03-29 13:26) [1]

>Форма в dll.

Это очень сложно. Поверь. На эту тему материала очень мало. Потому что это очень сложно. Если есть возможность - ищи другие пути. Packages, например. Они почти те же dll, но немного другие, и разработаны, в частности, и для того, чтобы в них размещались формы.

>Пытаюсь разобраться.

Молодец. Вот только, если тебе это действительно интересно, то делай это сам. Вряд ли кто-то тебе подскажет что-то. Потому что это очень сложно. Готовые рабочие решения есть, но с тобой ими никто делиться не будет.


 
EgorovAlex ©   (2010-03-29 13:36) [2]

Сарказм я конечно понимаю, но всё, что я нашёл крутится вокруг приведённого кода :(


 
Application   (2010-03-29 13:56) [3]

>Сарказм я конечно понимаю

И где ты увидел в моих словах сарказм?

но всё, что я нашёл крутится вокруг приведённого кода

"Покрутишься" недельку-другую, если хватит упорства - чего-то на коленке сваяешь. Но все равно будут лезть ошибки. Потому что, кроме сарказма, надо понимать еще что-то. А ты, похоже, не понимаешь. Повторяю: это сложно. Очень сложно. Надо использовать интерфейсы, разрабатывать схему межмодульного взаимодействия и многое другое.

А ты написал:

procedure Show(App: TApplication); stdcall;

exports
Show;


и надеешься, что тебе что-то тут подскажут? Подсказывать нечего, потому что то, то ты написал - писать нельзя. Почему? Потому что RTTI в разных модулях - разная. Добиться, чтобы она была одинаковой, можно, лишь используя пакеты. Не используя пакеты, так, как ты написал - писать нельзя. Надо использовать другие пути. Сложные. Которые тебе никто не расскажет и не разжует, потому что это сложно, и ты не поймешь до тех пор, пока не разберешься с этим сам.

DIXI


 
KSergey ©   (2010-03-29 13:56) [4]

Давайте вы разберетесь с тем, где именно возникает AV (на какой строчке) -а тама уже бум. думать.

В общем и целом - форма в ДЛЛ - неудачная идея.


 
KSergey ©   (2010-03-29 14:02) [5]

Ааа! вспомнил как это делается! (помню же, что было просто)

Эта, сложного ничего нет. Есть вот что:

1. Судя по uses - используются разные менеджеры памяти у exe и dll, при этом в dll передается ссылка на Application из хост приложения, которе выделено другим менеджером памяти и все такое, а вы изменяете его свойства в ДЛЛ, при этом переаллочируются участки памяти уже другим менеджером памятьи - короче то, что 1 раз срабатывает - тоже случайность чистой воды. Ну т.е. так делать нельзя в принципе.
Да и объекты Application в exe и dll - они разные, хоть и называются одинаково.

2. Если хочется почти все оставитьтак, то надо передавать в dll не Application, а Application.Handle, соответственно изменив тип параметра и в ДЛЛ присвоение тоже делать свойству Application.Handle.
Все срастется.


 
EgorovAlex ©   (2010-03-29 14:18) [6]

To Application,

Извини, тон не распознал :) Просто всё, что находил в интернете кажется простым и о таких тонкостях вообще никто ничего не говорил, только все говорят, что это очень просто и никаких проблем...

To KSergey,

Почему плохая? Потому-что проблем много? Я просто подумал некоторые формы было бы удобно туда кинуть, чтобы потом из разным проектов использовать...


 
EgorovAlex ©   (2010-03-29 14:20) [7]

Я с передачи хендла и начинал, но там выравнивания формы по главной не происходит, хотя форма и создаётся. Как выравнивать?


 
Leonid Troyanovsky ©   (2010-03-29 14:27) [8]


> EgorovAlex ©   (29.03.10 14:18) [6]

> некоторые формы было бы удобно туда кинуть, чтобы потом
> из разным проектов использовать...

Удобно в репозитарий кинуть.

--
Regards, LVT.


 
KSergey ©   (2010-03-29 14:43) [9]

> EgorovAlex ©   (29.03.10 14:20) [7]
> по главной не происходит, хотя форма и создаётся. Как выравнивать?

а) передать координаты
б) делать bpl
в) см. [8]


 
Игорь Шевченко ©   (2010-03-29 14:58) [10]

Тейксейра с Пачеко вроде давно разжевали все с формами в DLL ?


 
EgorovAlex ©   (2010-03-29 15:56) [11]

В общем прочитал я этих Тейкстеру с Пачекой - полезно иногда вспоминать первоисточники оказалось. Сделал как у них: в Application.Handle заношу хэндл экзешника, а выравнивание делаю передачей координат, вроде всё отлично работает :)

А какие ещё подводные камни могут быть потом? Почему многие считают формы в dll злом?


 
Сергей М. ©   (2010-03-29 16:00) [12]


> EgorovAlex ©   (29.03.10 15:56) [11]


Ты эту свою dll, насколько это видно из приведенного кода, собираешься использовать не только в дельфийских хост-приложениях ?


 
EgorovAlex ©   (2010-03-29 16:03) [13]

Сейчас у меня туда только хендл передаётся и выглядит примерно так:


procedure Show(hApp: THandle); stdcall;
begin
Application.Handle := hApp;
with TForm.Create(Application) do
try
  ShowModal;
finally
  Free;
end;
end;


До этого был ещё код запоминания и восстановления исходного хендла, но у Пачеки этого нет и у себя убрал


 
12 ©   (2010-03-29 16:37) [14]

слушай Application
я набил уже шишку. Пока что-то заработает - время уйдет.
потом все работает вроде - оппа! опять что-то не работает. Начинаем искать, находим, а время то не стоит..

короче, слушай Application - есть подозрение, что это ЮЗ :)


 
Германн ©   (2010-03-29 16:47) [15]


> есть подозрение, что это...

Не. Вышеназванный как правило не тыкает. :)


 
Leonid Troyanovsky ©   (2010-03-29 17:35) [16]


> EgorovAlex ©   (29.03.10 15:56) [11]

> А какие ещё подводные камни могут быть потом? Почему многие
> считают формы в dll злом?

Многие считают и dll злом :)

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-03-29 17:36) [17]

Leonid Troyanovsky ©   (29.03.10 17:35) [16]


> Многие считают и dll злом :)


количество многих равно единице :)


 
Leonid Troyanovsky ©   (2010-03-29 17:53) [18]


> Игорь Шевченко ©   (29.03.10 17:36) [17]

> > Многие считают и dll злом :)

> количество многих равно единице :)

Оптимист :)
http://msdn.microsoft.com/en-us/library/ms811694.aspx

Себя я даже вычеркнуть могу.

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-03-29 18:28) [19]

Leonid Troyanovsky ©   (29.03.10 17:53) [18]

Не увидел в статье по ссылке dll considered an evil


 
Leonid Troyanovsky ©   (2010-03-29 18:48) [20]


> Игорь Шевченко ©   (29.03.10 18:28) [19]

> Не увидел в статье по ссылке dll considered an evil

Его и не поминали, бо излучали оптимизм.

Мне, кста, комментарий
http://ru.wikipedia.org/wiki/DLL_hell понравился.

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-03-29 19:06) [21]

Leonid Troyanovsky ©   (29.03.10 18:48) [20]


> http://ru.wikipedia.org/wiki/DLL_hell


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

Бред какой-то. Жалко, эксперты руки выпрямить не советуют, это был бы наиболее оптимальный совет.


 
Leonid Troyanovsky ©   (2010-03-29 19:30) [22]


> Игорь Шевченко ©   (29.03.10 19:06) [21]

> Бред какой-то. Жалко, эксперты руки выпрямить не советуют,
>  это был бы наиболее оптимальный совет.

Конечно, это можно сформулировать проще:
Не используйте dll там, где без них можно обойтись.

Повторное использование кода легко реализовать обычными средствами
дельфи. Скажем, включил себе в проект юнит и пользуй.

А экономить дисковое пространство это не наша задача :)
Все равно, рано или поздно, дело сведется к использованию
для конкретного проекта конкретной библиотеки.

Ну, и поддерживать зоопарк разных версий из разных заповедников
это очень, IMHO, увлекательное и продуктивное занятие.

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-03-29 19:40) [23]

Leonid Troyanovsky ©   (29.03.10 19:30) [22]


> Не используйте dll там, где без них можно обойтись.


Не понимаю, зачем без них обходиться. Удобный механизм, лишаться его из-за того, что где-то у кого-то кривые руки, смысла нету.


> Повторное использование кода легко реализовать обычными
> средствами
> дельфи. Скажем, включил себе в проект юнит и пользуй.


А потом появляются два приложения, скомпилированные с разными версиями этого юнита и начинается промеж них камасутра с картинками.


> Все равно, рано или поздно, дело сведется к использованию
> для конкретного проекта конкретной библиотеки.


Обычно дело сводится к набору общих библиотек и набору вполне конкретных приложений, использующих для своих целей эти библиотеки.
Собственно, первый раз я с подобным использованием столкнулся еще на железной машине, с тех пор считаю, что страшилка DLLHell просто раздута :)


 
Leonid Troyanovsky ©   (2010-03-29 19:55) [24]


> Игорь Шевченко ©   (29.03.10 19:40) [23]

> Не понимаю, зачем без них обходиться. Удобный механизм,

А в чем удобства-то? LoadLibrary vs uses? Минус объекты, плюс
непредсказуемое время существования.

> А потом появляются два приложения, скомпилированные с разными
> версиями этого юнита

Если я скажу, что негоже своей команде пользовать чужые исходние,
то я, всего лишь, снова повторю совет by T.Tentser, чего бы мне не
хотелось, бо у мну нет его опыта на этот счет.
А представить, что команда не может уследить за своими исходниками,
но, тем не менее, легко справляется с поступлением на систему заказчика
к.л. библиотек из гондураса, мне как-то сложно :)

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

Набор на набор, декартово произведение :)

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-03-29 20:13) [25]

Leonid Troyanovsky ©   (29.03.10 19:55) [24]


> А в чем удобства-то? LoadLibrary vs uses?


ну да, в нем самом. Возможно изменить часть без изменения целого. Я себе с трудом представляю обновления Windows, если бы они происходили по принципу "один исходный модуль компилируется во всех, его использующих приложениях".

Более того, я с трудом представляю обновления нашей системы :)


 
Leonid Troyanovsky ©   (2010-03-29 20:32) [26]


> Игорь Шевченко ©   (29.03.10 20:13) [25]

> > А в чем удобства-то? LoadLibrary vs uses?

> ну да, в нем самом. Возможно изменить часть без изменения
> целого. Я себе с трудом представляю обновления Windows,
> если бы они происходили по принципу "один исходный модуль
> компилируется во всех, его использующих приложениях".

Dll, все равно, не то. Ну, если только подписывать, а это,
в конечном счете, один проект - одна библиотека.
Лучше уж COM, bpl, где хоть какие-то правила есть.

Наконец, пусть отдельные экзешники: сервисы, серверы и т.д.,
но не dll, а то, что дублируется код, да и фиг с ним, он же -re only.

> Более того, я с трудом представляю обновления нашей системы
> :)

Я тоже :)

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-03-29 20:42) [27]

Leonid Troyanovsky ©   (29.03.10 20:32) [26]


> Dll, все равно, не то. Ну, если только подписывать, а это,
>
> в конечном счете, один проект - одна библиотека.



> Лучше уж COM, bpl, где хоть какие-то правила есть


Я сильно извиняюсь, потерял нить дискуссии - мы конкретно о Delphiйских DLL говорим или о DLL вообще ?

Если конкретно о Delphi-йских, то их без run-time пакетов использовать можно с большими оговорками, если о DLL вообще, то все сказанное мной выше остается верным без изменений :)


 
Leonid Troyanovsky ©   (2010-03-29 20:50) [28]


> Игорь Шевченко ©   (29.03.10 20:42) [27]

> использовать можно с большими оговорками, если о DLL вообще,
>  то все сказанное мной выше остается верным без изменений
> :)

И я от своего не отступлюсь :)

Если б время, потраченное пытливыми умами на борьбу с длл,
примером чему явился уважаемый топикстартер, было потрачено
более продуктивно, то, глядишь, и проблем с длл не было бы.

--
Regards, LVT.


 
Германн ©   (2010-03-30 02:12) [29]

Позиция LVT мне гораздо больше по душе, чем позиция ИШ.
Но последнего я тоже понимаю после фразы
> Более того, я с трудом представляю обновления нашей системы
> :)
>

:)


 
Дмитрий Белькевич   (2010-03-30 12:40) [30]

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


> что где-то у кого-то кривые руки, смысла нету.


Если бы была возможность полностью контролировать все руки - свои, своих инсталляторов, чужих программ/инсталляторов, винды, её апдейтов, юзеров, админов - это сильно бы упростило задачу.

У меня, например, как-то раз были проблемы из-за какого-то кривого апдейта винды (XP) - мультимедийные дллки винды не могли создать несжатый avi файл и записать в него несколько несжатых кадров. К счастью, нашел готовый код, создающий несжатые avi (вернее переписал из mjpeg"а), выбросил все обращения к мультимедиа апи - проблема больше ни разу не возникала.


> Лучше уж COM, bpl, где хоть какие-то правила есть.


С COM"ом тоже бывают проблемы. Например, когда разные версии COM серверов (но с одинаковыми юидами) должны лежать в разных версиях проекта. Начинается COM hell - т.к. единомоментно может быть зарегистрирован только один из нескольких серверов (одна из нескольких дллок, содержащая сервер). У нас такие проблемы со сторонней COM дллкой - со StarBurn"ером.


>  а то, что дублируется код, да и фиг с ним, он же -re only.


А коду не обязательно дублироваться (имеется в виду сырцам, не экзешнику). Никто не мешает располагаемый в дллках код поместить в отдельные юниты и добавлять их в uses там, где они нужны. Ну а то, что дублируется код в экшениках - то, думаю, несколько мегабайт лишнего кода в современных условиях - это мизер. Дотнетные приложения могут таскать с собой почти 250 метров "счастья" и как-то мало кто этим грузится.

По теме. Форму в ддлке как-то делал, нормально работала. Вместе с неделфийским экзешником.

Создавал/показывал форму так:


procedure CreateForm(InstanceClass: TComponentClass; var Reference);
var
Instance: TComponent;
begin
Instance := TComponent(InstanceClass.NewInstance);
TComponent(Reference) := Instance;
try
 Instance.Create(nil);
except
 TComponent(Reference) := nil;
 raise;
end;
end;


Обращение к форме:


CreateForm(TForm1, Form1);
with Form1 do
begin
 ...
 ...
 ...
 ...
 ShowModal;
 ...
 ...
 ...
 Release;
end;


Секция uses:


uses
Windows,
SysUtils,
Classes;


Сама форма - отдельный юнит, как обычно. Не знаю, насколько это верно, но нормально работало, на нескольких сотнях инсталляций.


 
Игорь Шевченко ©   (2010-03-30 14:28) [31]

Дмитрий Белькевич   (30.03.10 12:40) [30]


> Ну а то, что дублируется код в экшениках - то, думаю, несколько
> мегабайт лишнего кода в современных условиях - это мизер.
>


Ты тоже поклонник камасутры


 
Дмитрий Белькевич   (2010-03-30 16:44) [32]


> Ты тоже поклонник камасутры


Ну, не больший, чем Майкрософт ;)


 
Дмитрий Белькевич   (2010-03-30 16:46) [33]

C десятью гигами дллок в дотнетной папке Подгорецкого.


 
Leonid Troyanovsky ©   (2010-03-30 16:56) [34]


> Дмитрий Белькевич   (30.03.10 12:40) [30]

> По теме. Форму в ддлке как-то делал, нормально работала.

Мне влом компилировать, но, ЕМНИП, на форме не будут
работать хинты, акшины и, возможно, контекстные меню.
Думаю, что это еще не все неприятности.
Да и модальная форма это еще цветы.

--
Regards, LVT.


 
evvcom ©   (2010-03-30 17:00) [35]


> С COM"ом тоже бывают проблемы.

Да проблемы можно построить на ровном месте. Для этого большого ума не надо.

> Например, когда разные версии COM серверов (но с одинаковыми
> юидами) должны лежать в разных версиях проекта.

Зачем? В СОМ есть версионность. Новая версия COM - старые интерфейсы без изменений, а новые добавляются. Таким образом старые версии проекта будут обращаться к старым интерфейсам, а в новой версии проекта используем новые интерфейсы. См. как реализованы майкрософтовские офис, IE.

> Начинается COM hell. ... У нас такие проблемы со сторонней COM дллкой - со StarBurn"ером.

А это значит вот как раз те самые кривые ручки. То, что какая-то там программерская контора написала COM-сервер, не дает никакой гарантии того, что он безупречен, что код пишут там одни гуру. Точно также там сидят такие как мы программисты, работающие за зарплату, и каждый хочет получать побольше. А работодатель зачастую хочет платить поменьше, вот и набирает неопытных студентов. А дядька над ними самый опытный уже запарился за ними подчищать, а то может и он уже уволился, и о проекте теперь известно, что кто-то там когда-то что-то писал, и делается это вроде так, хотя точно в этом никто не уверен.

А вот насчет bpl - имхо, лучше уж нормально написанная dll, чем bpl, привязанная к версии Delphi, под которой реализована и скомпилена.


> Создавал/показывал форму так:

А код такой ф топку, если используется не с рантайм пакетами. Рано или поздно, не понимая того, что в exe и dll код идентичный, но РАЗНЫЙ, ты получишь граблями.


 
Leonid Troyanovsky ©   (2010-03-30 17:11) [36]


> Leonid Troyanovsky ©   (30.03.10 16:56) [34]

> работать хинты, акшины и, возможно, контекстные меню.

Погнал, sorry.
TAction еще не успел проверить.

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-03-30 17:38) [37]

evvcom ©   (30.03.10 17:00) [35]


> А вот насчет bpl - имхо, лучше уж нормально написанная dll,
>  чем bpl, привязанная к версии Delphi, под которой реализована
> и скомпилена.


если все проекты собираются на одной и той же версии Delphi, включая как приложения, так и dll, чем плохи bpl ?
По моему скромному опыту версия Delphi меняется не часто.


 
Leonid Troyanovsky ©   (2010-03-30 19:07) [38]


> Leonid Troyanovsky ©   (30.03.10 17:11) [36]

> TAction еще не успел проверить.

Чего-то меня длл нынче совсем утомили :(

Смотрю на дельфийском хосте и удивляюсь.

Т.е., для чужих хостов нужно, на худой конец,
хоть Application.Handle назначить. Проверять не буду :)

Боже мой, чего меня туда заносит :(

--
Regards, LVT.


 
evvcom ©   (2010-03-30 19:34) [39]


> если все проекты собираются на одной и той же версии Delphi,
>  включая как приложения, так и dll, чем плохи bpl ?

Не все проекты... :)
Очень старые проекты на очень старых Delphi писаны, не очень старые на не очень старых и т.д. :)
Конечно, в любом случае соглашусь, лучше bpl использовать, чем передавать классы в обычные dll.


 
Дмитрий Белькевич   (2010-03-30 19:42) [40]


> Зачем? В СОМ есть версионность. Новая версия COM - старые
> интерфейсы без изменений, а новые добавляются. Таким образом
> старые версии проекта будут обращаться к старым интерфейсам,
>  а в новой версии проекта используем новые интерфейсы. См.
>  как реализованы майкрософтовские офис, IE.


Ну и dll"ки тоже как бы, в нормальных условиях, должны работать нормально. Однако dll hell имеем.



Страницы: 1 2 вся ветка

Текущий архив: 2011.10.30;
Скачать: CL | DM;

Наверх




Память: 0.6 MB
Время: 0.011 c
15-1309411014
Дмитрий С
2011-06-30 09:16
2011.10.30
Какой код ошибки http повесить, когда


2-1310381051
leon2011
2011-07-11 14:44
2011.10.30
Помогите разобраться с TextOutW


2-1310110990
leon2011
2011-07-08 11:43
2011.10.30
Как из UTF8 получить WideString


15-1309724999
Юрий
2011-07-04 00:29
2011.10.30
С днем рождения ! 4 июля 2011 понедельник


15-1309765210
PiterK
2011-07-04 11:40
2011.10.30
Обводка изображения