Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.06;
Скачать: CL | DM;

Вниз

Создание COM сервера   Найти похожие ветки 

 
Vitalik ©   (2004-08-26 10:27) [0]

Привет! Я пытаюст создать COM сервер в виде файла EXE. Помогите пжалста, оцените ход моих мыслей, что для этого нужно сделать!

Я бы не хотел пользоваться мастерами, потому что так не интересно и ничего не понятно ;)

Для этого делаю следующее:

0. создаю новый проект в Delphi, удаляю все модули с формами, application.initialization, application.run - к чертям.

Оставляем:
programm cnsCalc
begin
end.

Это и будет моей отправной точкой :)

1. Создаю (в новых отдельных модулях) несколько своих интерфейсов и реализующих их классов - не важно какие это COM объекты,
главное, что они будут содержаться в моём сервере.

2. Для того, чтобы COM сервер был COM сервером, нужно чтобы в нём была хотя бы одна фабрика классов (используя которую, можно будет найти любой интерфейс в сервере)

Фабрика классов (на сколько я понимаю) - это класс, реализующий интерфейс IClassFactory. Это вообще правильно?

Я выполнил этот класс просто:

 TFactory = class(TInterfacedObject, IClassFactory)
 private
   FServLocks: integer;
 protected
   function _Release: Integer; stdcall;
 public
   constructor Create;
   function CreateInstance(const unkOuter: IUnknown; const iid: TIID;
     out obj): HResult; stdcall;
   function LockServer(fLock: BOOL): HResult; stdcall;
 end;

constructor TFactory.Create;
begin
 FServLocks := 0;
end;

Ну методы _Release и LockServer я выполняю так:

function TFactory.LockServer(fLock: BOOL): HResult;
begin
 If FLock then
   FServLocks := InterlockedIncrement(FServLocks)
 else
   FServLocks := Interlockeddecrement(FServLocks)
end;
//Т.е. получается, клиентские приложения могут блокировать фабрику в памяти, чтобы она не выгружалась, пока все блокировки будут сняты? (код для этого метода я не сам придумал - у сишников дюзнул :)

function TFactory._Release: Integer; stdcall;
begin
 Result := InterlockedDecrement(FRefCount);

 if (FServLocks = 0) and (Result = 0) then
   Destroy;
end;

Ну и самое интересное - реализация метода CreateInstance, который, в моём понимании, получает от клиентской программы интерфейс, и если этот интерфейс реализуется на сервере, то нужно создать реализующий объект и вернуть ссылку на интерфейс. Для простоты я выполнил этот метод так:

function TFactory.CreateInstance(const unkOuter: IInterface;
 const iid: TIID; out obj): HResult;
var
 IC    : ICalc; //в одном из модулей моего проекта описан интерфейс ICalc. ICalc = interface...
 Calc  : TCalc; //...который реализуется классом TCalc. TCalc = class(TInterfacedObject, ICalc)
begin
 If IsEqualIID(iid, CLSID_Calc) then //CLSID - если это IID интерфейса ICalc
   begin
     Calc := TCalc.Create; //создаём реализующий объект в памяти...
     IC := Calc;
     result := IC.QueryInterface(iid, obj); //Так как в предке TCalc (TInterfacedObject) метод QueryInterface находится в секции protected, то обращаемся к этому методу через интерфейс...
   end;
end;

Ну вот вроде и всё пока... Возвращением соответствующего результата в остальных случаях (когда, например, передан неверный iid) пока голову не забиваем...

3. Теперь мне нужно сделать так, чтобы при запуске COM сервера моя фабрика классов регистрировалась в системе и клиентские программы могли получать на неё интерфейс.

Как это сделать?
Предполагаю, что нужно в точке входа в программу (begin ... end.) использовать функцию CoCreateInstance, или CoGetClassObject...
Но как ими правильно пользоваться? Тут для меня вообще начался тёмный лес :(

описана функция так:

STDAPI CoCreateInstance(

   REFCLSID rclsid, //Class identifier  - идентификатор класса?!?! Что это? Какого класса?
   LPUNKNOWN pUnkOuter, //Object is or isn"t part of an aggregate - а это что? Ну мы это пока не проходили, вроде как можно покаместь nil использовать :) Хотя, всё равно интересно :)
   DWORD dwClsContext, //Context for running executable code - это, насколько я понимаю, определяет в каком процессе будут работать COM объекты сервера - в процессе клиента, в другом процессе, в процессе другой машины и т.п.
   REFIID riid, //Interface identifier - это, как я понимаю, как раз идентификатор (IID) необходимого мне интерфейса... (например, интерфейса iCalc)
   LPVOID * ppv //Pointer to storage of interface pointer - а это указатель на интерфейс компонента, который мне нужен и который я получу, если павильно задам riid :)
  );

Вот.... Ну как? много я тут дров наломал? :) Насколько верно мое понимания создания COM серверов в файле EXE?
Этож блин, основа, тут нужно всё хорошо понимать! А пока сам не сделаешь...
Вот!
Так как, всё же, зарегистрировать фабрику классов при запуске сервера и как сделать так, чтобы клиентские программы могли использовать мою фабрику классов чтобы использовать COM объекты в моём COM сервере? :)

Спасибо!


 
Vitalik ©   (2004-08-26 13:07) [1]

Мдя... как мой вопрос оказался похож на
http://www.vserg.ru/doc/articles/combegin.html
:)
Кстати, статья классная, мне очень понравилась!


 
Vitalik ©   (2004-08-27 13:18) [2]

Упростим вопрос :)
В DLL для создания объекта фабрики классов используется экспортируемая функция DllGetClassObject.
А как создаётся этот COM - объект в случае, если COM сервер реализован в виде исполняемого файла?


 
Aleksey Pavlov ©   (2004-08-29 16:16) [3]

Сначала читаем "Основы COM" хотя бы до частичного просветления, потом идём сюда с вопросами =)))

По вопросу: любой (внешний(Local) или внутренний (in-proc)) сервер создаётся так или иначе с помощью фабрики классов данного класса COM-сервера. Откуда фабрика классов "знает" как создать сервер и как реализована DllGetClassObject написанно всё в той же книге.

P.S. а изучение COM лучше всё же начинать не с приведённой ссылки ;)


 
Vitalik ©   (2004-08-30 06:35) [4]

да где их взять-то "основы COM" эти? :(
Ну я вот читал Тенцера "Delphi и технология COM" но этот вопрос я не получил ответа :(
Там (по факту), как и везде - "пользуйтесь, ребята, мастерами"...

а больше книжек в продаже и нету на сегодня!


 
Vitalik ©   (2004-08-30 06:37) [5]

да где их взять-то "основы COM" эти? :(
Ну я вот читал Тенцера "Delphi и технология COM" но на этот вопрос я не получил ответа :(
Там (по факту), как и везде - "пользуйтесь, ребята, мастерами"...

а больше книжек в продаже и нету на сегодня!


 
Aleksey Pavlov ©   (2004-08-30 10:57) [6]

Dale Rogerson "Inside COM" Microsoft Press

В русском варианте:
Роджерсон  "Основы COM".

http://www.books.ru/shop/books/4668?partner=findbook

Стоит совсем недорого.

А вообще есть такая классная штука, как www.findbook.ru =)


 
Vitalik ©   (2004-08-30 12:59) [7]

О! Спасибо, Алексей Павлов!
Куплю обязательно, стоит и правда недорого :)

Одно настораживает... "товар закончился у основного поставщика" :) ну ничего, будем надеяться :)



Страницы: 1 вся ветка

Текущий архив: 2005.06.06;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.043 c
1-1116566276
SteppesSon
2005-05-20 09:17
2005.06.06
Exception


1-1116514489
Aleksandr.
2005-05-19 18:54
2005.06.06
Почему портится кодировка при копировании в буфер?


1-1116511807
Ada
2005-05-19 18:10
2005.06.06
Как мне открыть файл PDF из своего приложения?


3-1115113694
kyn66
2005-05-03 13:48
2005.06.06
Как добавить ключевой столбец в существующую таблицу Access ?


9-1110470642
electroowl
2005-03-10 19:04
2005.06.06
Помогите установить glscene!!!