Re[2]: Архитектура COM сервера
От: Hibiscus Россия  
Дата: 26.03.10 23:07
Оценка: 1 (1) +1
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, SkySniper, Вы писали:


SS>>Потом понял что при вызове методов с клиента сервер не знает какой именно клиент вызвал метод и понял что архитектуру придется здорово поменять, в принципе это не проблема, можно хоть заново все переписать.


Vi2>Дело в том, что в СОМе клиент не обладает или может не обладать интерфейсами


"может не обладать" --- а может и обладать . Посмотри на тему, которая называется disp-interfaces. С помощью этого можно заставить сервер вызывать методы интерфейса клиента. С этим надо быть осторожным, ибо зависание клиента в этом случае может привести к зависанию сервера (а сервер вроде должен быть безотказным ) ну там и прочая серверная лабуда, но уж если ты пишешь такой сервер, наверняка о них должен знать

По поводу идентификации клиента: можно немного усложнить архитектуру. Например, реализовать сервер в виде 2 частей: основной и представительской. Клиент должен создать себе представителя. Представитель содержит в себе какую-либо уникальную информацию, чтобы клиента по ней можно было идентифицировать. Самое простое: порядковый номер соединения, каждый раз увеличивающийся на 1). Клиент вызывает методы у представителя, который перенаправляет их основной части, добавляя эту уникальную информацию.

Может можно придумать что еще. Кстати, интересная задача, отпишись что у тебя получится итоге)))
Re[9]: Архитектура COM сервера
От: Vi2 Удмуртия http://www.adem.ru
Дата: 03.04.10 09:40
Оценка: 10 (1)
Здравствуйте, Jolly Roger, Вы писали:

JR>Боюсь, не совсем Вас понял, нельзя-ли чуть подробней?


VARIANT и SafeArray
Автор(ы):
Дата: 13.10.2002
, главы "VARIANT изнутри" и "VARIANT и структуры" или вся статья целиком. Там ответы на все вопросы. Если и после этого что-то останется непонятным, то милости просим снова сюда.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Архитектура COM сервера
От: SkySniper  
Дата: 26.03.10 13:45
Оценка:
Всем здравствуйте.
COM только начинаю изучать, так что прошу сильно не бить.
Имеется 2 приложения: сервер(сервис) и клиент, общающиеся через TCP.

class CServer
{
   ...
   CDeviceManager m_DeviceManager;
   std::vector<CClient*> m_Clients;
   ...
}

class CDeviceManager
{
   ...
   std::vector<CDevice*> m_Devices;
   ...
}


Алгоритм сервера, в общих чертах, такой:
1. При запуске, поиск неких подключенных устройств, заполнение m_Devices.
2. При подключении/отключении нового клиента соответственно заполнение m_Clients.
3. При получении команды от клиента вызов void CServer::processClientCommand(CClient* pClient).

Использую Visual Studio 2008, ATL.
Подскажите как можно построить архитектуру сервера используя COM?
Поиск по интернету практически ничего не дал кроме каши в голове .

Начал эксперименты с чего то примерно такого :

class ATL_NO_VTABLE CServer :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CServer, &CLSID_Server>,
    public IConnectionPointContainerImpl<CServer>,
    public CProxy_IServerEvents<CServer>,
    public IDispatchImpl<IServer, &IID_IServer, &LIBID_VideoServerLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
    DECLARE_CLASSFACTORY_SINGLETON(CServer);

Потом понял что при вызове методов с клиента сервер не знает какой именно клиент вызвал метод и понял что архитектуру придется здорово поменять, в принципе это не проблема, можно хоть заново все переписать.

Есть кое какие мысли, но не уверен в их правильности.
Например использовать что то типа этого при подключении клиента:

class ATL_NO_VTABLE CClient :
    public CComObjectRootEx<CComMultiThreadModel>,
    ...
{
public:
    DECLARE_CLASSFACTORY_AUTO_THREAD();

В этом случае при каждом подключении будет создаваться новый экземпляр клиента, но не знаю как это увязать с сервером.
dcom server
Re: Архитектура COM сервера
От: Vi2 Удмуртия http://www.adem.ru
Дата: 26.03.10 14:20
Оценка:
Здравствуйте, SkySniper, Вы писали:

SS>Потом понял что при вызове методов с клиента сервер не знает какой именно клиент вызвал метод и понял что архитектуру придется здорово поменять, в принципе это не проблема, можно хоть заново все переписать.


Дело в том, что в СОМе клиент не обладает или может не обладать интерфейсами, в то время как сервер обязан. Поэтому, если ты мыслишь в терминах интерфейсов (ну, классов), при вызове метода сервера клиент может передавать интерфейс, который его характеризует или по которому его можно оповещать. Кстати, можно задействовать тот же IServerEvents интерфейс, который клиент передал бы для подписки на события сервера.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Архитектура COM сервера
От: SkySniper  
Дата: 26.03.10 16:59
Оценка:
Передавать клиентом что то при вызовом каждого метода сервера для идентификации клиента мне тоже в голову приходило, но мне кжется это не лучшее решение. Я тут еще подумал что устройства тоже хорошо бы создавать как COM объекты и передавать их клиенту, если это возможно, т.к. тогда автоматом получаем возможность оповещать о событиях на конкретных устройствах, конкретных клиентов, имеющих ссылки на устройства.
Вопрос в том как это реализовать в коде?
Re[3]: Архитектура COM сервера
От: Vi2 Удмуртия http://www.adem.ru
Дата: 27.03.10 06:34
Оценка:
Здравствуйте, SkySniper, Вы писали:

SS>Я тут еще подумал что устройства тоже хорошо бы создавать как COM объекты и передавать их клиенту, если это возможно, т.к. тогда автоматом получаем возможность оповещать о событиях на конкретных устройствах, конкретных клиентов, имеющих ссылки на устройства.

SS>Вопрос в том как это реализовать в коде?

Да, эта идея неплоха. Есть статьи на сайте по поводу создания или подписки на события.
Как подключиться к событиям СOM-объекта на С++
Автор(ы): Владислав Чистяков

Как в ATL клиенте подписываться на события
Автор: Odi$$ey
Дата: 21.09.04


Могу набросать, как это выглядело бы на VB:
Dim WithEvents oServer As Server
Dim WithEvents oDevice As Device

Sub Main ' или Form_Load()

  Set oServer = GetObject(,"Server_ProgID") ' или CreateObject("Server_ProgID")
  Set oDevice = oServer.Device("параметры устройству")

  oDevice.DoSomething ...

End Sub

' методы интерфейса IServerEvents

Sub oServer_Exit()
...
End Sub

' методы интерфейса IDeviceEvents

Sub oDevice_DataRecieved()
...
End Sub
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: Архитектура COM сервера
От: SkySniper  
Дата: 27.03.10 09:09
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Да, эта идея неплоха. Есть статьи на сайте по поводу создания или подписки на события.

Vi2>Как подключиться к событиям СOM-объекта на С++
Автор(ы): Владислав Чистяков

Vi2>Как в ATL клиенте подписываться на события
Автор: Odi$$ey
Дата: 21.09.04


С созданием и подпиской на события я худо бедно разобрался, интересует созадние самих объектов на сервере (например тех же устройств) и передача их клиенту. Т.е. как я понимаю нужно будет испольховать фабрику классов примерно такую как при SINGLETON.
Re: Архитектура COM сервера
От: SkySniper  
Дата: 29.03.10 13:34
Оценка:
SS>Алгоритм сервера, в общих чертах, такой:
SS>1. При запуске, поиск неких подключенных устройств, заполнение m_Devices.
SS>2. При подключении/отключении нового клиента соответственно заполнение m_Clients.
SS>3. При получении команды от клиента вызов void CServer::processClientCommand(CClient* pClient).

Что то я все никак продвинуться не могу, теперь постараюсь задавать более конкретные вопросы.

Допустим класс устройства выглядит так:

class ATL_NO_VTABLE CDevice :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CDevice, &CLSID_Device>,
    public IConnectionPointContainerImpl<CDevice>,
    public CProxy_IDeviceEvents<CDevice>,
    public IDispatchImpl<IDevice, &IID_IDevice, &LIBID_VideoServer2Lib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
    CDevice()
    {
    }

DECLARE_CLASSFACTORY_SINGLETON(CDevice);

//DECLARE_REGISTRY_RESOURCEID(IDR_DEVICE)
DECLARE_NO_REGISTRY()


BEGIN_COM_MAP(CDevice)
    COM_INTERFACE_ENTRY(IDevice)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(CDevice)
    CONNECTION_POINT_ENTRY(__uuidof(_IDeviceEvents))
END_CONNECTION_POINT_MAP()


    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {
    }

private:
//тут методы и поля данных интерфейса
...
public:
//тут методы и поля данных интерфейса
...
};

//OBJECT_ENTRY_AUTO(__uuidof(Device), CDevice)
OBJECT_ENTRY_NON_CREATEABLE_EX_AUTO(__uuidof(Device), CDevice)


Класс сервера, при запуске должен будет искать устройства и занести их в m_Devices:

class ATL_NO_VTABLE CServer :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CServer, &CLSID_Server>,
    public IConnectionPointContainerImpl<CServer>,
    public CProxy_IServerEvents<CServer>,
    public IDispatchImpl<IServer, &IID_IServer, &LIBID_VideoServer2Lib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
    CServer()
    {
    }

DECLARE_CLASSFACTORY_SINGLETON(CServer);

DECLARE_REGISTRY_RESOURCEID(IDR_SERVER)


BEGIN_COM_MAP(CServer)
    COM_INTERFACE_ENTRY(IServer)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()

BEGIN_CONNECTION_POINT_MAP(CServer)
    CONNECTION_POINT_ENTRY(__uuidof(_IServerEvents))
END_CONNECTION_POINT_MAP()


    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {
    }
private:
   std::vector<CDevice*> m_Devices;


   size_t CServer::AddDevice()
   {
    [b]//как тут создать устройство?

    m_Devices.push_back(device);

    return m_Devices.size();
   }[/b]
private:
//тут методы и поля данных интерфейса
...
public:
//тут методы и поля данных интерфейса
...
};

OBJECT_ENTRY_AUTO(__uuidof(Server), CServer)


Выделил жирным шрифтом код в котором не уверен.
Re[2]: Архитектура COM сервера
От: sidorov18 США  
Дата: 29.03.10 13:45
Оценка:
Здравствуйте, SkySniper, Вы писали:

SS> size_t CServer::AddDevice()

SS> {
SS> [b]//как тут создать устройство?

CComObject<CDevice>* pdevice = NULL;
CComObject<CDevice>::CreateInstance( &pdevice );//создаеться с счетчик ссылок равным 0-ю

pdevice->AddRef();//где-то при удалении нужно вызвать Release или хранить CDevice* в умном указателе.
SS> m_Devices.push_back(pdevice);

SS> return m_Devices.size();

SS> }[/b]
Re[3]: Архитектура COM сервера
От: SkySniper  
Дата: 30.03.10 05:51
Оценка:
А как теперь передать клиенту в другом процессе интерфейс IDevice одного из устройств из std::vector<CDevice*> m_Devices.
Что то типа:
HRESULT CServer::get_Device(IDevice* *dev)
{
//что тут?
//return m_Devices[0]->QueryInterface(__uuidof(IDevice), (void**)dev); //это нужно как то отмаршалить?
}
Re[4]: Архитектура COM сервера
От: sidorov18 США  
Дата: 30.03.10 06:21
Оценка:
Здравствуйте, SkySniper, Вы писали:

SS>А как теперь передать клиенту в другом процессе интерфейс IDevice одного из устройств из std::vector<CDevice*> m_Devices.

SS>Что то типа:
SS>HRESULT CServer::get_Device(IDevice* *dev)
SS>{
SS> //что тут?
SS> //return m_Devices[0]->QueryInterface(__uuidof(IDevice), (void**)dev); //это нужно как то отмаршалить?
SS>}

Если ты создаешь ATL exe server — у тебя должно создаваться 2 проекта в сборке(правильно я solution перевел?). один из них proxy-stub dll. он генерируется автоматически на основе библиотеки типов(то, что в *.idl файле в основном проекте).
В этом случае о маршаллинге можно забыть — он происходит без участия программиста. т.е. твой код корректен.
иначе — не пробовал, не знаю
Re: Архитектура COM сервера
От: SkySniper  
Дата: 31.03.10 08:43
Оценка:
Еще вопрос. В книге "Inside COM" написано: "интерфейс совместимый с Автоматизацией наследует IDispatch и использует только такие типы параметров, которые можно поместить в VARIANT. Для таких типов OLEAUT32.DLL выполняет маршалинг автоматически.".
Что делать если например необходимо передавать параметр типа RECT? Не очень то хочется передавать 4 параметра вместо 1го, даже в таком простом случае, не говоря уже о более сложных структурах.
Re[2]: Архитектура COM сервера
От: Vi2 Удмуртия http://www.adem.ru
Дата: 31.03.10 08:57
Оценка:
Здравствуйте, SkySniper, Вы писали:

SS>Еще вопрос. В книге "Inside COM" написано: "интерфейс совместимый с Автоматизацией наследует IDispatch и использует только такие типы параметров, которые можно поместить в VARIANT. Для таких типов OLEAUT32.DLL выполняет маршалинг автоматически.".

SS>Что делать если например необходимо передавать параметр типа RECT? Не очень то хочется передавать 4 параметра вместо 1го, даже в таком простом случае, не говоря уже о более сложных структурах.

Описываешь структуру и передаешь ее — структура также является "совместимой с Автоматизацией" и имеет тип VT_RECORD.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Архитектура COM сервера
От: SkySniper  
Дата: 31.03.10 14:05
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, SkySniper, Вы писали:


SS>>Еще вопрос. В книге "Inside COM" написано: "интерфейс совместимый с Автоматизацией наследует IDispatch и использует только такие типы параметров, которые можно поместить в VARIANT. Для таких типов OLEAUT32.DLL выполняет маршалинг автоматически.".

SS>>Что делать если например необходимо передавать параметр типа RECT? Не очень то хочется передавать 4 параметра вместо 1го, даже в таком простом случае, не говоря уже о более сложных структурах.

Vi2>Описываешь структуру и передаешь ее — структура также является "совместимой с Автоматизацией" и имеет тип VT_RECORD.


А можно чуть подробнее?
У меня сервер на C++, клиент на Delphi.

Запись в IDL файле Visual Studio:
    [id(3), helpstring("method ResizeWindow")] HRESULT ResizeWindow([in] LONG channel, [in] RECT inRect, [in] RECT outRect);

Определение прототипа:
    STDMETHOD(ResizeWindow)(LONG channel, RECT inRect, RECT outRect);


Делаю в Delphi Import Type Library, генерируется:

  tagRECT = packed record
    left: Integer;
    top: Integer;
    right: Integer;
    bottom: Integer;
  end;
...
  IDevice = interface(IDispatch)
    procedure ResizeWindow(channel: Integer; inRect: tagRECT; outRect: tagRECT); safecall;
  end;
...
  IDeviceDisp = dispinterface
    procedure ResizeWindow(channel: Integer; inRect: {??tagRECT}OleVariant; 
                           outRect: {??tagRECT}OleVariant); dispid 3;
  end;
Re[4]: Архитектура COM сервера
От: SkySniper  
Дата: 02.04.10 09:03
Оценка:
SS>
SS>  tagRECT = packed record
SS>    left: Integer;
SS>    top: Integer;
SS>    right: Integer;
SS>    bottom: Integer;
SS>  end;
SS>...
SS>  IDevice = interface(IDispatch)
SS>    procedure ResizeWindow(channel: Integer; inRect: tagRECT; outRect: tagRECT); safecall;
SS>  end;
SS>...
SS>  IDeviceDisp = dispinterface
SS>    procedure ResizeWindow(channel: Integer; inRect: {??tagRECT}OleVariant; 
SS>                           outRect: {??tagRECT}OleVariant); dispid 3;
SS>  end;
SS>


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

procedure TForm1.Panel1Resize(Sender: TObject);
var
  rect1: tagRECT;
begin
  if (DeviceObj<>nil) then begin
    rect1 := tagRect(Panel1.BoundsRect);
    DeviceObj.ResizeWindow(1, rect1, rect1);
  end;
end;


Следовательно он использует proxy/stub DLL автоматизации(Ole32.dll), и мне нет необходимости создавать регистрировать свой proxy/stub?
Но смущает меня вот этот код, насколько я понимаю он не верен, в каких случаях будет использоваться dispinterface?
  IDeviceDisp = dispinterface
    procedure ResizeWindow(channel: Integer; inRect: {??tagRECT}OleVariant; 
                           outRect: {??tagRECT}OleVariant); dispid 3;


Будет ли верным решением использовать подобный код вызова методов DeviceObj.ResizeWindow(1, rect1, rect1)?
Re[5]: Архитектура COM сервера
От: Vi2 Удмуртия http://www.adem.ru
Дата: 02.04.10 19:59
Оценка:
Здравствуйте, SkySniper, Вы писали:

SS>Следовательно он использует proxy/stub DLL автоматизации(Ole32.dll), и мне нет необходимости создавать регистрировать свой proxy/stub?

SS>Но смущает меня вот этот код, насколько я понимаю он не верен, в каких случаях будет использоваться dispinterface?
SS>  IDeviceDisp = dispinterface
SS>    procedure ResizeWindow(channel: Integer; inRect: {??tagRECT}OleVariant; 
SS>                           outRect: {??tagRECT}OleVariant); dispid 3;

Для вопросов по Дельфи есть специальный форум. Здесь же мы можем слегка подтолкнуть в нужном направлении. IDevice, похоже, наследует от IDispatch и является дуальным (dual) интерфейсом, т.е. состоит как бы из двух интерфейсов — диспинтерфейса (dispinterface) и обычного интерфейса (custom). Они отличаются способом вызова методов, другое прочтение этого обстоятельства — позднее и раннее связывание.

Поскольку IDevice наследует от IDispatch, то СОМ предоставляет средства для создания proxy/stub, которым для работы нужна зарегистрированная библиотека типов TLB. При ее отсутствии нужно предоставить свою версию proxy/stub DLL.

Почему Дельфи меняет тип параметра — одному Дельфи известно (еще, пожалуй, дельфистам). Видимо так нужно в языке.

SS>Будет ли верным решением использовать подобный код вызова методов DeviceObj.ResizeWindow(1, rect1, rect1)?


Это как Дельфи позволит. VB, например, позволит такой синтаксис и для IDevice, и для IDeviceDisp.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Архитектура COM сервера
От: Jolly Roger  
Дата: 03.04.10 03:27
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>VB, например, позволит такой синтаксис [...] и для IDeviceDisp.


Вы уверены? А как он передаст RECT в Invoke, RECT ведь не совместим с VARIANT?
"Нормальные герои всегда идут в обход!"
Re[7]: Архитектура COM сервера
От: Vi2 Удмуртия http://www.adem.ru
Дата: 03.04.10 05:28
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Вы уверены? А как он передаст RECT в Invoke, RECT ведь не совместим с VARIANT?


... структура также является "совместимой с Автоматизацией" и имеет тип VT_RECORD
Автор: Vi2
Дата: 31.03.10


Структура RECT упаковывается в VARIANT, т.к. она описана в IDL при описании метода, и, следовательно, предоставляет всю информацию для упаковки ее в VARIANT.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[8]: Архитектура COM сервера
От: Jolly Roger  
Дата: 03.04.10 06:21
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Структура RECT упаковывается в VARIANT, т.к. она описана в IDL при описании метода, и, следовательно, предоставляет всю информацию для упаковки ее в VARIANT.


Боюсь, не совсем Вас понял, нельзя-ли чуть подробней?

Ведь dispinterface — сущность времени компиляции, предназначенная для ID-binding'а, в run-time за ней обычный IDispatch, в вызов Invoke которого компилятор преобразует вызовы методов диспинтерфейса. В Invoke-же параметры передаются через массив VARIANT'ов, один параметр — один VARIANT. Мы можем каждое из полей RECT поместить в отдельный VARIANT, но целиком в один — нет.

Совместимость с OLE означает, что информация о способе маршалинга каждого из полей RECT "вшита" в универсальный маршалер, а библиотека типов предоставляет информацию о расположении полей. При этом не обязательно даже интерфейс наследовать от IDispatch, вполне подойдёт IUnknown. В результате универсальный маршалер имеет возможность маршалировать и демаршалировать RECT как единый параметр, при этом VARIANT как таковой не нужен и не используется. Так оно работает при early binding'е.

Но ID binding и late binding — дело другое. Первый от второго отличается только тем, что во время компиляции все ID уже известны, и нет нужды их запрашивать в ран-тайме. При этом в ран-тайме библиотека типов не нужна и не используется, информации о структуре RECT у универсального маршалера нет, а упаковать её в один VARIANT невозможно из-за отсутствия соответствующей, известной маршалеру константы VT_RECT. А работа через dispinterface — это и есть ID binding.

ИМХО, единственный способ передать RECT при late or ID binding'е — SafeArray. Ну или дополнитедьный метод, в котором каждое из полей будет представлено отдельным параметром.

Я в чём-то не прав?
"Нормальные герои всегда идут в обход!"
Re[9]: Архитектура COM сервера
От: SkySniper  
Дата: 03.04.10 06:42
Оценка:
Спасибо, за ответы.
Для меня осталось несовсем понятным когда именно используется early binding, а когда late binding?
Re: Архитектура COM сервера
От: SkySniper  
Дата: 06.04.10 06:55
Оценка:
Всем привет, снова вопросы
Имеется SINGLETON сервер, к нему подключаются клиенты.
Каким образом передавать информацию от сервера конкретному клиенту?
Ведь при использовании ConnectionPoint сервер будет оповещать всех подключенных к нему клиентов.
Может создавать COM объект в клиенте передавать его интерфейс серверу и вызывать его методы? Но не придется ли при этом настраивать доступ и для клиентской машины?
Может еще что то посоветуете?
Re[2]: Архитектура COM сервера
От: sidorov18 США  
Дата: 07.04.10 06:38
Оценка:
Здравствуйте, SkySniper, Вы писали:

SS>Всем привет, снова вопросы

SS>Имеется SINGLETON сервер, к нему подключаются клиенты.
SS>Каким образом передавать информацию от сервера конкретному клиенту?
SS>Ведь при использовании ConnectionPoint сервер будет оповещать всех подключенных к нему клиентов.
Можно и конкретных клиентов. Реализация ведь генерируется мастером(ну в ATL по крайней мере). И оповещение происходит следующим образом: в цикле у каждого клиента вызывается соответствующий метод. На этом этапе можно как-то фильтровать эти вызовы.

SS>Может создавать COM объект в клиенте передавать его интерфейс серверу и вызывать его методы? Но не придется ли при этом настраивать доступ и для клиентской машины?

Ну метод Connection Point делает то же самое, только через IDispatch. т.е. Если у вас есть Connection Point, значит на клиенте у вас COM классы. И раз настраивать доступ не пришлось — то и с добавлением новых интерфейсов у клиентских классов проблем быть не должно.
Но с DCOM(я так понимаю — у вас сервер через сеть) не сталкивался — последняя реплика только логический вывод.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.