Использование интерфейсов и TInterfaceListDelphi , Технологии , OLEИспользование интерфейсов и TInterfaceList
Оформил: DeeCo { The Classes unit provides a class TInterfaceList which is a TList that can store interfaces (yes, those that are descendants of IUnknonw). If you need to store interfaces do not use a TList, use TInterfaceList, otherwise you will run into trouble. Here is how to do it: } type IMyInterface = interface procedure AMethod; end; type TMyObject = class(TInterfacedObject, IMyInterface) procedure AMethod; end; {....} var InterfaceList: TInterfaceList; MyInt: IMyInterface; {....} MyInt := TMyObject.Create; InterfaceList.Add(MyInt); {....} MyInt := IMyInterface(InterfaceList[Index]); MyInt.AMethod; {Easy, but there is a catch. The following code will crash: } {... declarations like above ...} InterfaceList.Add(TMyObject.Create); MyInt := IMyInterface(InterfaceList[0]); MyInt.AMethod; // -> Access Violation { Why is that? That is because instead of storing the IMyInterface if TMyObject we stored its IUnknown interface in the InterfaceList. Retrieving this resulted in an invalid typecast of a non-IMyInterface interface to IMyInterface. The resulting interface pointer pointed to a IUnknown interface which simply does not have the AMethod method. When we tried to call this method, the code tried to get the corresponding method pointer from the interface's VMT and got some garbage instead. The following, minimally changed code works: } {... declarations like above ...} InterfaceList.Add(IMyInterface(TMyObject.Create)); MyInt := IMyInterface(InterfaceList[0]); MyInt.AMethod; // -> Access Violation { That is, because the explicit typecast to IMyInterface before adding the TMyObject object to the list returned the IMyInterface interface of TMyObject rather than the IUnknown interface. But since IMyInterface is a descendant interface of IUnknown, it can still be stored in the InterfaceList. Confused? Yes, so was I. It took me ages to figure out what was wrong with my program that crashed unexpectedly. I hope this will help others to avaoid this problem or at least find the reason why their programs don't behave as they should. } Статья обсуждает важность использования Основной вопрос заключается в том, что Например, в коде:
В списке хранится интерфейс Чтобы решить этоissue, вам нужно явно кастовать объект в правильный интерфейс перед добавлением его в список. Например:
Таким образом, вы обеспечиваете, что в списке хранится интерфейс Статья также предупреждает о том, что нельзя использовать В целом, статья подчеркивает важность понимания, как интерфейсы хранятся в списках, и как явное кастование может помочь избежать общих проблем с хранением интерфейсов. Использование интерфейсов и TInterfaceList: при хранении интерфейсов в списке не рекомендуется использовать обычный TList, а вместо этого следует использовать TInterfaceList, иначе может возникнуть проблема с типом каста. Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |