Створення com-сервера, delphisite

Для створення COM-сервера Delphi надає широкий набір майстрів, що автоматизують виконання рутинних завдань і дозволяють програмісту сконцентруватися на реалізації функціональності. Майстри доступні за допомогою команди меню File-> New, на закладці ActiveX
Щоб зробити COM-сервером EXE-файл, Ви повинні просто додати в нього модуль з COM-об'єктом. Для створення COM-сервера у вигляді DLL Ви повинні спочатку створити бібліотеку, оформлену з урахуванням вимог COM. Це робиться за допомогою майстра «ActiveX Library». При його виборі буде створено новий проект, який реалізує DLL і згенерований наступний код:

Створена DLL експортує функції, необхідні для роботи COM і Ви можете не турбуватися про рутинної роботи і відразу приступити до реалізації COM-сервера.Для цього виберіть майстер «COM-об'єкт».
Від заповнення полів цієї форми залежить реалізація створюваного COM-об'єкта
ClassName Ім'я класу Delphi, що реалізує COM-сервер. Майстер створить заготівлю класу з цим ім'ям. Під цим же ім'ям COM-сервер буде зареєстрований в реєстрі.
Instansing Визначає режим створення COM-об'єктів. Параметр може набувати таких значень: Internal Об'єкт може використовуватися тільки усередині цього додатка. Single Instance Створення кожного примірника об'єкта призводить до запуску нового екземпляра додатка-сервера. Після створення об'єкта «фабрика об'єктів» додатка видаляє інформацію про себе з системного списку зареєстрованих фабрик, що змушує COM при створенні нового об'єкта запустити додаток сервер в новому процесі Multiple Instance Після створення екземпляра об'єкта «фабрика" не видаляє себе зі списку зареєстрованих. При створенні запиті на створення нового об'єкту COM виявить її в цьому списку і запросить створення у тій же фабрики і новий екземпляр об'єкта буде створений в тому ж додатку. Іншими словами для створення всіх об'єктів даного типу будт запущено не більше одного примірника сервера. Цей параметр має сенс тільки для EXE-серверів, для DLL він ігнорується.

Threading Model потокового модель сервера. Дія цього параметра залежить від типу сервера (EXE або DLL) Single Немає ніякої підтримки потоків. Для DLL-сервера при реєстрації не буде створено параметр ThreadingModel Для EXE-сервера вказівку цього параметра (на відміну від будь-якого іншого) не призведе до встановлення прапора IsMultiThread, буде створена STA. Зазвичай ця модель використовується для Internal серверів Apartment Для DLL сервера в реєстрі буде створений параметр ThreadingModel = Apartment, для EXE - створена STA Free Для DLL сервера в реєстрі буде створений параметр ThreadingModel = Free, для EXE - створена MTA Both Для DLL сервера в реєстрі буде створений параметр ThreadingModel = Both, для EXE - створена MTA

Include Type Library Установка цього прапорця призводить до включення в сервер бібліотеки типів - спеціального двійкового ресурсу, що описує реалізовані сервером інтерфейси, їх методи і параметри виклику. COM надає стандартні засоби роботи з бібліотеками типів. Зокрема, Delphi може імпортувати наявну в сервері бібліотеку типів і автоматично побудувати по ній інтерфейсний модуль для роботи з ним. При використанні бібліотеки типів інтерфейси описуються за допомогою Type Library Editor. Об'єкт успадковується від TTypedComObject Якщо цей прапорець вимкнений, то об'єкт успадковується від TComObject. Це більш легка реалізація сервера.

Implemented Interfaces Це поле дозволено, тільки якщо об'єкт не використовує бібліотеку типів. У цьому випадку Ви повинні самі описати інтерфейси в коді своєї програми і перерахувати їх в цьому полі, наприклад «ITest, IAnotherTest»

Mark interface Oleautomation Установка цього прапора робить COM-сервер сумісним з OLE Automation. Ви повинні використовувати в методах інтерфейсу тільки сумісні з OLE Automation типи даних. Це необхідно, якщо Ви хочете передавати посилання на інтерфейс між різними «кімнатами». Така операція, яка називається маршаллінг інтерфейсів вимагає написання спеціальної proxy / stub DLL. Однак, якщо інтерфейс позначений як Oleautomation цю роботу виконує маршаллер OLE і Ви будете позбавлені від зайвої роботи.
. Для підтримки Oleautomation маршаллінг необхідно, щоб: • сервер був успадкований від TTypedComObject (реалізація IDispatch не обов'язкова) • всі методи інтерфейсу повинні бути оголошені як safecall. Якщо Ви створюєте інтерфейс успадкований від IUnknown, то за замовчуванням всі його методи оголошуються як stdcall. Щоб створити safecall методи необхідно в діалозі Tools-> Environment Options на закладці Type Library встановити перемикач Safecall function mapping в значення All v-table interfaces
Сервер без бібліотеки типів
Такий сервер, якщо він не реалізує інтерфейс IMarshall, може працювати тільки в одній «кімнаті» з клієнтом, тому його слід використовувати тільки для In-Process серверів з потокової моделлю ідентичною клієнту.
При створенні сервера, що не включає бібліотеку типів Ви повинні вказати майстру реалізовані їм інтерфейси. Зазначимо ім'я інтерфейсу ITest. По завершенні роботи майстра буде створено наступний модуль:

Windows, ActiveX, Classes, ComObj;

TTest = class # 40; TComObject, ITest # 41;

TComObjectFactory. Create # 40; ComServer, TTest, Class_Test,

'Test'. ''. ciMultiInstance, tmApartment # 41; ;

Якщо Ви створюєте COM-сервер, який може використовуватися різними клієнтами (а не тільки в рамках конкретного проекту, в якому специфікації клієнтів жорстко задані) не рекомендується робити сервери без підтримки маршаллінг даних, оскільки в цьому випадку неможливо забезпечити гарантоване знаходження її в одній «кімнаті »з клієнтом. Якщо ви все ж робите такий сервер - необхідно відобразити необхідні специфікації клієнта в документації на нього.
Подивимося на згенерований код докладніше. Особливий інтерес викликає секція Initialization. У ній створюється екземпляр «фабрики об'єктів» - COM-сервера, що реалізує інтерфейс IClassFactory2. До нього COM буде звертатися для створення екземпляра об'єкта Test. VCL автоматично реалізує всю рутинну роботу по взаємодії з COM.
Для реалізації сервера потрібно написати інтерфейсний модуль з описом реалізованого інтерфейсу. Крім цього, винесемо в нього опис константи Class_Test і додамо його в рядок uses модуля Unit1

procedure ShowIt # 40; S: String # 41; ;

Цей модуль містить всю необхідну інформацію для використання сервера і повинен використовуватися при компіляції клієнта.
Доповнимо код COM-об'єкта реалізацією методів реалізованого інтерфейсу:

Windows, ActiveX, Classes, ComObj, TestInterface;

TTest = class # 40; TComObject, ITest # 41;

procedure ShowIt # 40; S: String # 41; ;

MessageBox # 40; 0. PChar # 40; S # 41 ;. NIL. 0 # 41; ;

TComObjectFactory. Create # 40; ComServer, TTest, Class_Test,

'Test'. ''. ciMultiInstance, tmApartment # 41; ;

Відкомпільоване проект, ми отримаємо файл Project1.dll
Останнім кроком є ​​реєстрація COM-сервера.
Введемо в командному рядку: «regsvr32 project1.dll»
Якщо все було зроблено правильно, на екрані має з'явитися повідомлення про успішну реєстрацію: «DllRegisterServer in Project1.dll succeeded».
Можна приступати до написання клієнта. Для цього створимо новий проект, додамо в модуль з його головною формою рядок uses TestInterface і напишемо наступний код:

uses TestInterface, ComObj;

procedure TForm1. Button1Click # 40; Sender: TObject # 41; ;

Test: = CreateComObject # 40; Class_Test # 41; as ITest;

Test. ShowIt # 40; 'Hi' # 41; ;

Як видно з цього прикладу створення і використання COM-сервера не складніше, ніж робота зі звичайними класами Delphi. Сервер без бібліотеки типів є хорошим вибором для реалізації COM-серверів, використовуваних всередині проекту, оскільки для його використання потрібен інтерфейсний модуль. При передачі сервера іншим розробникам Вам доведеться передати їм цей модуль і, при необхідності, перевести його на іншу мову (наприклад, С).
Сервер з бібліотекою типів
Бібліотека типів - це спеціальний двійковий ресурс, що описує інтерфейси і методи, реалізовані COM-сервером. Крім наявності бібліотеки типів сервер повинен підтримувати інтерфейс IProvideClassInfo. У Delphi такий сервер реалізується шляхом успадкування його від TTypedComObject. Для цього залиште прапорець Include Type Library в майстра створення COM-об'єкта включеним.
Створимо COM-сервер у вигляді EXE (зрозуміло, він може бути також створений і вигляді DLL).
Спочатку створимо новий проект (File-New Application), а потім додамо в нього COM-об'єкт.
Якщо не відключати прапорець Include Type Library, то майстер створить вже не один, а два модуля. Перший з них нагадує створений раніше.

Windows, ActiveX, Classes, ComObj, Project1_TLB, StdVcl;

TTest1 = class # 40; TTypedComObject, ITest1 # 41;

TTypedComObjectFactory. Create # 40; ComServer, TTest1, Class_Test1,

ciMultiInstance, tmApartment # 41; ;

ITest1 = interface # 40; IUnknown # 41;

function ShowIt # 40; const S: WideString # 41 ;. HResult; stdcall;

А в модулі Unit1:

TTest1 = class # 40; TTypedComObject, ITest1 # 41;

function ShowIt # 40; const S: WideString # 41 ;. HResult; stdcall;

function TTest1. ShowIt # 40; const S: WideString # 41 ;. HResult;

Нам залишається лише написати реалізацію методу:

function TTest1. ShowIt # 40; const S: WideString # 41 ;. HResult;

MessageBoxW # 40; 0. PWideChar # 40; S # 41 ;. NIL. 0 # 41;

Result: = S_OK; // Стандартний код успішного завершення

Для реєстрації сервера досить один раз запустити його на комп'ютері клієнта.