Конференция "Основная" » Приложение и DLL [D7, WinXP]
 
  • ilkz (18.01.08 21:09) [0]
    Всем привет!
    Вопрос такой:
    Есть приложение, которое загружает 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 © (18.01.08 21:30) [1]
    Может лучше все же пакеты начать использовать, на dll?
  • DVM © (18.01.08 21:31) [2]
    Тем более, что твоя dll все одно может быть использована только в проекте на Delphi.
  • OSokin (18.01.08 21:37) [3]
    Application.Components[i] is TForm


    Может надо "is TForm1"?
  • ilkz (18.01.08 21:38) [4]
    А я и не собираюсь работать над проектом в других средах и языках. Я просил подсказать решение моей проблемы, а не посылать меня использовать то, чего я не знаю.
  • ilkz (18.01.08 21:40) [5]
    Osokin - Чушь говоришь, ибо в библиотеке нету TForm1. Мне надо проверить принадлежность объектов списка Components классу TForm.
  • DVM © (18.01.08 21:42) [6]

    >  не посылать меня использовать то, чего я не знаю.

    Пакеты будут тебе удобнее мне кажется.


    > Application.Components[i] is TForm

    А почему это должно работать вообще? Класс твоей формы какой? TForm1 небось.
  • ilkz (18.01.08 21:45) [7]
    TForm1: ERROR: Undeclared identifier;
  • DVM © (18.01.08 21:45) [8]
    Ты зря меня не слушаешь про пакеты. В приложении и dll в каждом свои менеджеры памяти и RTTI. И твой TForm в приложении не равен TForm в dll
  • ilkz (18.01.08 21:48) [9]
    Ага. Это уже что-то... Буду разбираться, но для начала хотелось бы решить описанную мной проблему, а не переходить на пакеты...
  • DVM © (18.01.08 21:49) [10]

    > а не переходить на пакеты...

    на них не надо переходить их надо включить.
  • ilkz (18.01.08 21:51) [11]
    и как это сделать?
  • Leonid Troyanovsky © (18.01.08 21:51) [12]

    > ilkz   (18.01.08 21:38) [4]

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

    А чего ж ты взялся использовать то, чего не знаешь.

    --
    Regards, LVT.
  • DVM © (18.01.08 21:52) [13]

    > и как это сделать?

    Project->Options->Build With Packages
  • ilkz (18.01.08 21:54) [14]

    > А чего ж ты взялся использовать то, чего не знаешь.
    >


    Я не не знаю, а изучаю и пытаюсь понять собственные ошибки.
  • DVM © (18.01.08 21:56) [15]

    > f:=TForm(Application.Components[i]);

    Кстати, так тоже можно оставить. Это альтернативный вариант, но несколько менее удобный.


    > ilkz

    не забудь включить пакеты и проекте dll и в основной программе.
  • ilkz (18.01.08 21:59) [16]
    Ага, включил пакеты и все заработало! Спасибо DVM и всем остальным за помощь!
  • Германн © (19.01.08 00:32) [17]

    > ilkz   (18.01.08 21:59) [16]
    >
    > Ага, включил пакеты и все заработало!

    Будешь переносить программу на другой компьютер, не забудь перенести и пакеты тоже.
  • Amoeba © (19.01.08 15:08) [18]

    > Кто может объяснить где косяк

    Объяснение здесь:
    http://www.delphikingdom.com/asp/viewitem.asp?catalogid=831
    см. раздел "Чудо шестое"
  • ilkz (19.01.08 16:31) [19]
    Читаю... Вникаю помаленьку...
  • ilkz (19.01.08 17:29) [20]
    Мне непонятно следующее:
    Мне что - для решения проблемы надо использовать пакеты, таская за собой рантаймы?

    Или же необходимо пользоваться методами ClassName и ClassNameIs и далее приведением типов в стиле TForm(FindedResult)?

    Или оба эти варианта имеют право на жизнь, но каждый хорош по-своему?
  • DVM © (19.01.08 17:32) [21]

    > Или оба эти варианта имеют право на жизнь, но каждый хорош
    > по-своему?

    Оба я же уже говорил.
  • DVM © (19.01.08 17:34) [22]
    Правда вариант с f:=TForm(Application.Components[i]); он, как бы сказать, не совсем корректен, но работать будет.
  • ilkz (19.01.08 17:38) [23]
    А почему он не совсем корректен?
  • DVM © (19.01.08 17:44) [24]

    > А почему он не совсем корректен?

    Ну, дело в том, что приводятся один к другому совершенно разные классы. Но так как по внутреннему устройству они абсолютно одинаковы, то приведение возможно. В общем случае может оказаться, что классы будут различны - тогда возникнет ошибка приведения. Такое возможно, имхо, если dll делалась на одной версии Delphi, а основное приложение в другой.
  • ilkz (19.01.08 17:48) [25]
    Ага, понятно.
  • Amoeba © (19.01.08 21:36) [26]

    > DVM ©   (19.01.08 17:44) [24]
    >
    >
    > > А почему он не совсем корректен?
    >
    > Ну, дело в том, что приводятся один к другому совершенно
    > разные классы. Но так как по внутреннему устройству они
    > абсолютно одинаковы, то приведение возможно. В общем случае
    > может оказаться, что классы будут различны - тогда возникнет
    > ошибка приведения. Такое возможно, имхо, если dll делалась
    > на одной версии Delphi, а основное приложение в другой.

    Одна или разные версии Delphi - это не важно. В любом случае даже одинаковые классы в приложении и DLL при компиляции в одной и той же версии Delphi, будут различными (VMT, в частности, у каждого будет своя), то в результате проверка через is/as даст отрицательный результат. Если компилировать с пакетами (но версия, естественно, должна быть одной и той же), тогда результат уже будет положительным.
  • DVM © (19.01.08 21:44) [27]

    > Amoeba ©  

    Это все само собой. Я не совсем о том. Я о приведении.
    От версии к версии, например, у того же класса TForm могут появиться дополнительные новые методы или свойства. Если приложение компилируется в старой версии делфи, а длл в новой, то при попытке приведения из в длл переданного в ее процедуру указателя к типу TForm и последующем вызове какого либо метода может получиться ошибка. А в случае одной и той же версии делфи ошибки может и не быть.
  • MetalFan © (20.01.08 01:23) [28]
    можно попробовать вместо is проверять ClassName например...
  • DVM © (20.01.08 11:05) [29]

    > MetalFan ©

    посмотри внимательно код в [0]
 
Конференция "Основная" » Приложение и DLL [D7, WinXP]
Есть новые Нет новых   [134482   +35][b:0][p:0.001]