Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2011.10.30;
Скачать: [xml.tar.bz2];

Вниз

Форма в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.005 c
2-1310113245
Andrey34324
2011-07-08 12:20
2011.10.30
Выборка из Listview уникальных значений.


11-1238343292
codemaster
2009-03-29 20:14
2011.10.30
KOL и Классы


3-1265218398
ther
2010-02-03 20:33
2011.10.30
как получить код исключения в запросе? ADO+sql sever


15-1309445404
картман_
2011-06-30 18:50
2011.10.30
московское метро


2-1310371260
.dzmitry
2011-07-11 12:01
2011.10.30
поиск в локальной БД





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский