![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Приложение и DLL [D7, WinXP]
ilkz © (2008-01-18 21:09:00)Всем привет!
Вопрос такой:
Есть приложение, которое загружает dll-ку и вызывает в ней процедуру, которая должна как-то воздействовать на компоненты формы приложения.
Процедура в dll описана так:
procedure PluginRun(Application: TApplication);
var i: integer;
begin
for i:=0 to Application.ComponentCount - 1 do
begin
//if (Application.Components[i].ClassName='TForm1') then //работает
if Application.Components[i] is TForm then //не работает
begin
showmessage('ok');
//f:=TForm(Application.Components[i]); //работает
f:=Application.Components[i] as TForm; //не работает
f.Caption:='hello';
end;
end;
end;
В главном приложении она вызывается так:
plugin.RunProc(Application);
где в поле RunProc record'а plugin хранится адрес процедуры PluginRun.
Проблема вот в чем.
Код, помеченный комментариями "работает" - работает.
Но код, помеченный комментарием "не работает" - не работает: не срабатывает условие if Application.Components[i] is TForm then. Долблюсь уже несколько часов и не могу понять почему? Гугль уже облазил, но кроме первого решения ничего не нашел. Кто может объяснить где косяк и как его вылечить?
DVM (2008-01-20 11:05:00) [1]
> MetalFan ©
посмотри внимательно код в [0]
MetalFan (2008-01-20 01:23:00) [2]можно попробовать вместо is проверять ClassName например...
DVM (2008-01-19 21:44:00) [3]
> Amoeba ©
Это все само собой. Я не совсем о том. Я о приведении.
От версии к версии, например, у того же класса TForm могут появиться дополнительные новые методы или свойства. Если приложение компилируется в старой версии делфи, а длл в новой, то при попытке приведения из в длл переданного в ее процедуру указателя к типу TForm и последующем вызове какого либо метода может получиться ошибка. А в случае одной и той же версии делфи ошибки может и не быть.
Amoeba (2008-01-19 21:36:00) [4]
> DVM © (19.01.08 17:44) [24]
>
>
> > А почему он не совсем корректен?
>
> Ну, дело в том, что приводятся один к другому совершенно
> разные классы. Но так как по внутреннему устройству они
> абсолютно одинаковы, то приведение возможно. В общем случае
> может оказаться, что классы будут различны - тогда возникнет
> ошибка приведения. Такое возможно, имхо, если dll делалась
> на одной версии Delphi, а основное приложение в другой.
Одна или разные версии Delphi - это не важно. В любом случае даже одинаковые классы в приложении и DLL при компиляции в одной и той же версии Delphi, будут различными (VMT, в частности, у каждого будет своя), то в результате проверка через is/as даст отрицательный результат. Если компилировать с пакетами (но версия, естественно, должна быть одной и той же), тогда результат уже будет положительным.
ilkz (2008-01-19 17:48:00) [5]Ага, понятно.
DVM (2008-01-19 17:44:00) [6]
> А почему он не совсем корректен?
Ну, дело в том, что приводятся один к другому совершенно разные классы. Но так как по внутреннему устройству они абсолютно одинаковы, то приведение возможно. В общем случае может оказаться, что классы будут различны - тогда возникнет ошибка приведения. Такое возможно, имхо, если dll делалась на одной версии Delphi, а основное приложение в другой.
ilkz (2008-01-19 17:38:00) [7]А почему он не совсем корректен?
DVM (2008-01-19 17:34:00) [8]Правда вариант с f:=TForm(Application.Components[i]); он, как бы сказать, не совсем корректен, но работать будет.
DVM (2008-01-19 17:32:00) [9]
> Или оба эти варианта имеют право на жизнь, но каждый хорош
> по-своему?
Оба я же уже говорил.
ilkz (2008-01-19 17:29:00) [10]Мне непонятно следующее:
Мне что - для решения проблемы надо использовать пакеты, таская за собой рантаймы?
Или же необходимо пользоваться методами ClassName и ClassNameIs и далее приведением типов в стиле TForm(FindedResult)?
Или оба эти варианта имеют право на жизнь, но каждый хорош по-своему?
ilkz (2008-01-19 16:31:00) [11]Читаю... Вникаю помаленьку...
Amoeba (2008-01-19 15:08:00) [12]
> Кто может объяснить где косяк
Объяснение здесь:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=831
см. раздел "Чудо шестое"
Германн (2008-01-19 00:32:00) [13]
> ilkz (18.01.08 21:59) [16]
>
> Ага, включил пакеты и все заработало!
Будешь переносить программу на другой компьютер, не забудь перенести и пакеты тоже.
ilkz (2008-01-18 21:59:00) [14]Ага, включил пакеты и все заработало! Спасибо DVM и всем остальным за помощь!
DVM (2008-01-18 21:56:00) [15]
> f:=TForm(Application.Components[i]);
Кстати, так тоже можно оставить. Это альтернативный вариант, но несколько менее удобный.
> ilkz
не забудь включить пакеты и проекте dll и в основной программе.
ilkz (2008-01-18 21:54:00) [16]
> А чего ж ты взялся использовать то, чего не знаешь.
>
Я не не знаю, а изучаю и пытаюсь понять собственные ошибки.
DVM (2008-01-18 21:52:00) [17]
> и как это сделать?
Project->Options->Build With Packages
Leonid Troyanovsky (2008-01-18 21:51:00) [18]
> ilkz (18.01.08 21:38) [4]
> и языках. Я просил подсказать решение моей проблемы, а не
> посылать меня использовать то, чего я не знаю.
А чего ж ты взялся использовать то, чего не знаешь.
--
Regards, LVT.
ilkz (2008-01-18 21:51:00) [19]и как это сделать?
DVM (2008-01-18 21:49:00) [20]
> а не переходить на пакеты...
на них не надо переходить их надо включить.