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

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

Передача методу COM-сервера объекта(TClientDataSet) в параметре


Robin ©   (2002-07-31 12:19:00) 

Помогите в следующем:
  Есть COM-объект (Automation Object).
В методе COM-объекта создаю форму и показываю ее.
На форме лежит DBGrid, DataSource и ClientDataSet.

В вызывающей программе есть связка:
  DataBase, Query, Provider и ClientdataSet.

Вопрос: как связать ClientDataSet вызывающей программы с ClientDataSetом
        из COM-объекта, чтобы в нем на форме в DBGridе получил данные
        от вызывающей программы.

P.s. : при реализации выше описанного через DLL результат получал через
       передачу ClientDataSeta в параметре функции DLL.


Romkin   (2002-08-14 22:32:00) [1]

Насколько понял, нужен просто MIDAS server в dll, так будет проще всего. Я вижу два варианта
1. Создать ActiveX library а в ней RemoteDataModule, а подключиться действительно можно через TDCOMConnection - что мешает? Просто не указывать имя хоста, и будет подгрузка
2. Тоже самое, но для подключения вызывать CreateOleObject/CreateCOMObject и др., с прямым преобразованием к IAppServer (Delphi 5?), и вручную работать с данными через методы этого интерфейса
3. Реализовать собственный T...Connection по аналогии с TDCOMConnection, это просто, там буквально два или три метода

2 А. Н. Оним а то, что если используешь COM, то передавать только интерфейсы - поддерживаю полностью


Robin   (2002-08-01 15:21:00) [2]

2 А. Н. Оним   (31.07.02 18:19)

Спасибо за разъяснения.
Немножко тут продвинулся передавая в COM не ClientDataSet, а
ClientDataSet.Data. Но в COM-объекте тогда получается  "подвисший" ClientDataSet, т.е. без Providerа.

2 DiamondShark ©   (31.07.02 18:10)

Но чего то не догоняю: ведь TRemoteDatamodule - тоже COM-объект.
То есть приходим к DCOMConnection. Или я не прав?
 Можно пожалуйста поподробнее.


А. Н. Оним   (2002-07-31 18:19:00) [3]

 Полагаю, что DiamondShark прав и есть более простые решения этой проблемы (но сам я, признаться, подолгу не работал ни с DataSet'ами, ни с RemoteDataModul'ями) и COM кажется притянутым здесь за уши.
 Назначение IPersonal очень простое. Передать экземпляру CoClass ссылку на DataSet. Это можно сделать тысячью способов и обойтись без этого COM-интерфейса, но у меня просто правило такое - доступ к СOM объекту (даже внутри его сервера) только через его COM интерфейсы. Не нравится - не надо.


DiamondShark   (2002-07-31 18:10:00) [4]

А что, TRemoteDatamodule, TDatasetProvider уже отменили?


Robin   (2002-07-31 17:56:00) [5]

А. Н. Оним   (31.07.02 17:16) >

 Спасибо за мысль.
 Пойду вчитаюсь во II-й том Стива Тейксера.
Бо пока не очень все понятно: как реализовать
IDataSet (т.е. в моем случае IClientDataSet) и в чем идея IPersonal?

 Если можно, немножко разъясните.

 



Robin   (2002-07-31 17:41:00) [6]

А. Н. Оним   >

 Задача то простая:

 Есть несколько программ, которые используют одни и те же формы (Справочник клиентов и др.),которые в свою очередь отображают
информацию одного или нескольких наборов данных.

 Если форма меняется, то приходится перекомпилировать все проекты, использующие форму (:

 Эту беду попробовал решить через DLL - вроде ничего.

 Но в итоге решил сделать через COM.
 Сценарий определил такой:
 1.) Есть сервер приложений (MIDAS), в котором живут
     компоненты доступа к БД ORACLE через ODAC (OraSession,
     OraQuery, OraProvider);
 2.) Есть клиентские приложения, обращающиеся к серверу
     приложений через DCOM. В этих приложениях живут
     TClientDataSetы.
 3.) Есть набор форм, используемые клиентскими приложениями.
     Эти формы то и отображают информацию из наборов данных,
     получаемую от клиентских приложений.
     Связь [IN, OUT] с ClientDataSetом нужна, чтобы сообщить
     клиентскому приложению об изменениях набора данных,
     произведенных в форме COM-объекта.

 Пункты 1.) и 2.) реализовал, а 3.) - в печали и тумане.
 Кидать в каждую форму COM-объекта компонент DCOMConnection
 не хотелось бы (:

 
Еж ли что не так нагородил,
то буду очень благодарен за разъяснения.




А. Н. Оним   (2002-07-31 17:16:00) [7]

Можно попробовать так:
1. --Клиент--
 Клиент содержит COM объект-обёртку, что реализует пару интерфейсов. Например, IDataSet и IPersonal.
* IDataSet содержит примерно те же методы, что и TDataSet
* IPersonal позволяет назначить объекту управляемый им DataSet.
 Клиент создаёт экземпляр такого кокласса, и через IPersonal передаёт ему экземпляр DataSet'а. Так как и DataSet и COM объект в одном процессе (InProc) - это пройдёт. Предполагается, что клиентский COM объект реализует IDataSet перенаправлением вызовов метода этого интерефейса на назначенный ему через IPersonal экземпляр DataSet.
2. --Сервер--
 Сервер выставляет ConnectionPoint, позволяющий принимать такие обёртки.
3. --Клиент--
 Клиент посылает серверу такую обёртку (например, через IConnectionPoint сервера).
4.  --Сервер--
 На Сервер есть класс, который является наследником DataSet, но перенаправляет вся вызовы своих методов (делегирует вызовы) на объект обёртку, а ещё конкретней на его интерфейс IDataSet, полученный от клиента.

 В этой схеме клиент может менять данные в своём реальном DataSet'е, а сервер, обладающий прокси обёртки клиента, дёргает через проксие клиентский объект, тот, в свою очередь, дёргает назначенный ему DataSet, а уже тот и выполняет все операции. По идее, всё должно работать.


А. Н. Оним   (2002-07-31 16:55:00) [8]

В DLL да ещё и на одной машине такие фокусы как передача экземпляров класса всегда будет проходить, так как и сервер и клиент живут в одном адрессном пространстве и всё что нужно сделать, так это обратиться к одному участку памяти. Правда я не гарантирую, что это будет работать, если клиент и сервер будут скомплированы на разных версиях Delphi. Но пока это прекрасно получается и переданная тобой ссылка на экземпляр класса DataSet (как указатель на область памяти) будет иметь смысл для сервера.
 Как только клиент и сервер живут в разных адрессных пространствах - всё летит кувырком и указатель на область памяти клиента для сервера теряет всякий смысл. DataSet не является COM объектом, поэтому его передача в вызове метода не приведёт к процессу маршлалинга (создания прокси клиентского экземпляра кокласса на сервере) и его передача как в случае InProc взаимодействия невозможна.
 Не очень всё-таки понимаю, что за задача решается, но могу предложить следующий общий подход: реализовать в серверном коклассе методы обмена информацией между клиентом и сервером. Когда на клиенте происходят изменения, то клиент посылает обновлённые значения на сервер и наоборот, сервер посылает изменённые значения в качестве CallBack'ов клиенту через клиентский Sink объект. Для Callback'ов Посмотри интерфейсы IConnectionPointContainer, IConnectionPoint. Если ты пишешь в Delphi, то вопрос обратных вызовов рассматривается, например, во II томе Стива Тейксера (Delphi 5 руководство разработчика) со страницы 245.
 Нельзя ли поподробней рассказать о решаемой задаче?  


Наверх

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