Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

сервис и COM [Delphi, Windows]


Brenagwynn ©   (2007-01-18 14:25:00) 

Есть некий Win32 сервис, из которого наружу торчит интерфейс и есть программа-конфигуратор, которая получает некоторые данные при помощи этого интерфейса. Ниже приведу несколько кусков кода, которые помогут пониманию проблемы.
В сервисе есть класс:
TConnectionPoolManager = class(TObject)
 private
   fPools: TObjectList;
   fAllPoolSize: Integer;
   function GetPoolCount: Integer;
   function GetPool(aIndex: Integer): TConnectionPool;
 public
   constructor Create(aPoolSize: Integer);
   destructor Destroy; override;
   function AcquireConnection(aServer, aSchema, aUserName, aPassword: String): TConnectionItem;
   procedure ReleaseConnection(aConn: TConnectionItem);

   property AllPoolSize: Integer read fAllPoolSize;
   property PoolCount: Integer read GetPoolCount;
   property Pools[Index: Integer]: TConnectionPool read GetPool;
 end;
...
constructor TConnectionPoolManager.Create(aPoolSize: Integer);
begin
 fPools := TObjectList.Create;
 fPools.OwnsObjects := True;
end;

destructor TConnectionPoolManager.Destroy;
begin
 FreeAndNil(fPools);
 inherited;
end;
...
function TConnectionPoolManager.GetPoolCount: Integer;
begin
 Result := fPools.Count;
end;

function TConnectionPoolManager.GetPool(aIndex: Integer): TConnectionPool;
begin
 Result := TConnectionPool(fPools[aIndex]);
end;

Вот интерфейс
IHRMDataService = interface(IUnknown)
   ['{C311580A-8AC5-4B69-834D-5B6DA89BD9DE}']
   function Get_PoolCount: Integer; stdcall;
   function Get_Servers(Index: Integer; out Value: PChar): HResult; stdcall;
   function Get_Schemas(Index: Integer; out Value: PChar): HResult; stdcall;
 end;

И реализация:
function THRMDataService.Get_PoolCount: Integer;
begin
 Result := -1;
 if Assigned(g_Manager) then
   Result := g_Manager.PoolCount;
end;

function THRMDataService.Get_Servers(Index: Integer;
 out Value: PChar): HResult;
begin
 Result := S_FALSE;
 Value := '';
 if Assigned(g_Manager) then
 begin
   Result := S_OK;
   Value := PChar(g_Manager.Pools[Index].Server);
 end;
end;

function THRMDataService.Get_Schemas(Index: Integer;
 out Value: PChar): HResult;
begin
 Result := S_FALSE;
 Value := '';
 if Assigned(g_Manager) then
 begin
   Result := S_OK;
   Value := PChar(g_Manager.Pools[Index].Schema);
 end;
end;

Где g_Manager описан в отдельном юните:
unit uGlobals;

interface
uses uConnectionPoolManager;

var
 g_Manager: TConnectionPoolManager;

implementation
uses SysUtils;

initialization
 g_Manager := TConnectionPoolManager.Create(3);

finalization
 FreeAndNil(g_Manager);

end.


Собственно, проблема в следующем. Сервис работает, данные выдает (это http-сервер на определенном порту). Но если я к нему пытаюсь достучаться из конфигуратора (через COM), то мне возвращаются только нули и пустые строки.
procedure TForm1.Button1Click(Sender: TObject);
var
 s: IHRMDataService;
 c: PChar;
begin
 s := CreateComObject(CLASS_HRMDataService) as IHRMDataService;
 try
   Memo1.Lines.Add(Format('Pool count: %d',[s.Get_PoolCount])); // ВЫДАЕТ 0, хотя их точно не 0, потому что сервис работает
   s.Get_Servers(0, c);
   Memo1.Lines.Add(c); // пустая строка, что ГАРАНТИРОВАНО неправда, потому что сервис работает
 finally
   s := nil;
 end;
end;

По требованию предоставлю полный текст программы.


umbra   (2007-03-13 15:08:00) [1]

пример того, как можно использовать СОМ в сервисе можно посмотреть в http://code.progler.ru/get/259


tesseract   (2007-03-12 11:44:00) [2]


> надо бы для COMIHRMDataService = interface(IDispatch)


Это для OLE для Com как раз Iunknown.


isasa   (2007-03-11 11:17:00) [3]

Сразу бросилось в глаза

IHRMDataService = interface(IUnknown)

надо бы для COM
IHRMDataService = interface(IDispatch)


VladimirSh   (2007-03-11 02:12:00) [4]


> Все, разобрался. Ерунду написал. CreateComObject аж никак
> не будет использовать существующий инстанс, а просто запустит
> еще один экземпляр, у которого есессно все по нулям :(


У меня такая же проблема, срочно нужна помощь.

Как это решается, и что нужно сделать вместо CreateComObject?
Понимаю, что нужно вместо создания нового объекта найти в сервисе предыдущий инстанс Co... класса и вернуть указатель на него.

Помогите, люди добрые!!!


tesseract   (2007-01-20 17:47:00) [5]

> CreateComObject аж никак не будет использовать существующий
> инстанс,


Может и существующий использовать. Зависит от Threading model.


Brenagwynn   (2007-01-18 16:46:00) [6]

Все, разобрался. Ерунду написал. CreateComObject аж никак не будет использовать существующий инстанс, а просто запустит еще один экземпляр, у которого есессно все по нулям :(


tesseract   (2007-01-18 16:17:00) [7]

откуда PChar/string в COM? Только WideString ака OleString;

И пошаговую отладку никто не отменял.


Наверх

Титульная страница Поиск, карта сайта Написать письмо