Робота з об’єктами в DLL стор
Delphi site: daily Delphi-news, documentation, articles, review, interview, computer humor.
Якщо в DLL необхідно передати покажчик на об'єкт, створений в основному додатку, або навпаки, використовувати в додатку, що викликає, створений в DLL об'єкт, виникає проблема несумісності об'єктів. Типовий приклад коду, що ілюструє цю проблему, наведено нижче:
if 0 is TButton then ShowMessage('Кнопка') el se
Якщо обидва ці методи реалізовані в додатку, що викликає, то при клацанні на кнопці у формі з'явиться повідомлення "Кнопка". Якщо ж метод WhatObject реалізувати в DLL, то який би об'єкт не був вказаний як параметр, завжди з'являтиметься повідомлення "Незрозуміло, що це таке". Таким чином, можна зробити абсолютно коректний висновок, що не можна створити об'єкт в одному модулі, а використовувати його в іншому.
Чому робота з об'єктами в DLL реалізована саме в такий спосіб? Справа в тому, що програма і DLL можуть бути реалізовані різними мовами програмування. Відповідно, навіть за однакових назв класів кількість змінних у класі та/або їх розмір та/або порядок їх слідування можуть різнитися. Те саме стосується і методів класу. Тому в цьому випадку оператор is завжди повертає False, а оператор as генерує виняток.
І тим не менше в DLL можна використовувати об'єкти, створені в додатку, що викликає, і навпаки. Для цього необхідно, щоб і DLL, і головний додаток були реалізовані однією і тією ж мовою програмування. Нижче наведено приклад такого коду:
Метод ChangeColor реалізований у DLL, а метод ButtonlClick – у додатку. І DLL, і програма створені в Delphi. Виклик методу ChangeColor буде коректно працювати, якщо як параметрвказувати на об'єкт типу i Form (або нащадка TForm). Однак у DLL не можна перевірити тип об'єкта перед його приведенням до типу TForm, тому, якщо використовувати як параметр інший об'єкт, відбудеться запис у непередбачуване місце у пам'яті, і добре, якщо відразу ж буде згенеровано виняток.
Технологія СОМ надає альтернативний спосіб вирішення цієї проблеми, дозволяючи створювати об'єкти в одному модулі, а застосовувати в іншому. Для цього використовуються інтерфейси. Приклади реалізації інтерфейсів наведено у розділі 1.