Конференция "Corba" » сервис и COM [Delphi, Windows]
 
  • Brenagwynn (18.01.07 14:25) [0]
    Есть некий 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;


    По требованию предоставлю полный текст программы.
  • tesseract © (18.01.07 16:17) [1]
    откуда PChar/string в COM? Только WideString ака OleString;

    И пошаговую отладку никто не отменял.
  • Brenagwynn (18.01.07 16:46) [2]
    Все, разобрался. Ерунду написал. CreateComObject аж никак не будет использовать существующий инстанс, а просто запустит еще один экземпляр, у которого есессно все по нулям :(
  • tesseract © (20.01.07 17:47) [3]
    > CreateComObject аж никак не будет использовать существующий
    > инстанс,


    Может и существующий использовать. Зависит от Threading model.
  • VladimirSh © (11.03.07 02:12) [4]

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


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

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

    Помогите, люди добрые!!!
  • isasa © (11.03.07 11:17) [5]
    Сразу бросилось в глаза

    IHRMDataService = interface(IUnknown)

    надо бы для COM
    IHRMDataService = interface(IDispatch)
  • tesseract © (12.03.07 11:44) [6]

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


    Это для OLE для Com как раз Iunknown.
  • umbra © (13.03.07 15:08) [7]
    пример того, как можно использовать СОМ в сервисе можно посмотреть в http://code.progler.ru/get/259
 
Конференция "Corba" » сервис и COM [Delphi, Windows]
Есть новые Нет новых   [134431   +10][b:0][p:0.002]