-
Ищется пример передачи ссылки на созданный объект (интерфейс) в другой процесс. Что то сам не осилил пока.
-
> Ищется пример
sconnect.pas
-
Что то я там не нашел передачу в другой процесс. Хотелось бы примерчик двух приложений. В одном создали объект. В другом получили на него ссылку и вызвали метод.
-
> В одном создали объект. В другом получили на него ссылку > и вызвали метод
IPC? RPC? DCOM? sconnect из той же оперы
-
Я просто только недавно за КОМ принялся. Я так понимаю sconnect - это бибиотека, которая делает то, что мне надо? Ну а примера ни у кого нет, как ее использовать? В хелпе что то не густо про sconnect
-
> Ну а примера ни у кого нет, как ее использовать? В хелпе > что то не густо про sconnect
Вариантов много, в том числе и передача процессу ссылки на экземляр самого себя, или через IStream.
-
> _Z_ (01.04.08 11:58) [2] > > Что то я там не нашел передачу в другой процесс
Ты же про маршаллинг спросил ? Вот SConnect как раз и иллюстрирует "потроха" этого страшного слова)
-
> в том числе и передача процессу ссылки на экземляр самого > себя
Вот эта передача ссылки меня и интересует. Может кто нибудь набросает примерчик передачи (любым методом)?
Просто в моей книге по COM есть только пример внутрипроцессной передачи, а вот такой нет.
-
Вот допустим есть такой код:
type
ITest=Interface
['']
procedure TestProc(s:string);
End;
TTest=class (TInterfacedObject, ITest)
procedure TestProc(s:string);
End;
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
public
end;
procedure TTest.TestProc(s: string);
begin
ShowMessage(s);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ComObj.TestProc('Test from ComServer');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ComObj:=TTest.Create;
end;
Все понятно, когда из одного процесса использую. А вот теперь я хочу вызывать методы объекта ComObj (именно того экземпляра, который создался вместе с формой1). Как мне из приложения 2 получить ссылку на ComObj? Т.е. создаю еще одно приложение:
type
ITest=Interface
['']
procedure TestProc(s:string);
End;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
ComObj:ITest;
implementation
procedure TForm1.Button1Click(Sender: TObject);
begin
ComObj.TestProc('!!!');
end;
Вот как мне получить ссылку на ComObj, который я создал в приложении1?
-
> как мне получить ссылку на ComObj, который я создал в приложении1
При такой реализации - никак.
Интерпроцессным взаимодействием на базе COM/DCOM заведует ОС, а твои приложения никоим образом не известили ОС о своих намерениях.
-
> При такой реализации - никак. > > Интерпроцессным взаимодействием на базе COM/DCOM заведует > ОС, а твои приложения никоим образом не известили ОС о своих > намерениях.
Ок, я догадывался, что я тут чего то не допонял. Может ли кто то ткнуть носом, как доделать реализацию сервера, чтобы я мог решить свою задачу? Может где то в инете статья есть или готовый пример?
-
> как доделать реализацию сервера
Проще будет ее не доделать, а переделать с нуля, танцуя от
File -> New... -> ActiveX -> COM Object
Статей в Тырнете на эту тему воз и тележка, в т.ч. и с примерами.
-
> File -> New... -> ActiveX -> COM Object > > Статей в Тырнете на эту тему воз и тележка, в т.ч. и с примерами. >
Вот я пока не нашел примеров, хотел здесь и спросить. Где их лучше поискать. Пока что то никак.
-
> Где их лучше поискать
Например, в книге Эрика Хармона "Разработка СОМ-приложений в среде Делфи"
-
> Например, в книге Эрика Хармона "Разработка СОМ-приложений > в среде Делфи"
Книга то и у меня есть (Делфи 6 и технология COM). Но в моей нету того, что я ищу. Но да ладно. Для начала хотя бы просто делаю создание объекта в области памяти сервера из клиента по этой книге (кстати вот точно из нее есть и в инете отрывок: http://www.interface.ru/fset.asp?Url=/borland/decom_1.htm): Сервер сделал через мастер и как по инструкции (включая библиотеку типов). Сам сервер внутри себя нормально создает объект и все работает. Теперь делаю другое приложение: var
Form1: TForm1;
ClntComObj:ITest2;
implementation
uses ActiveX, ComObj;
procedure TForm1.Button1Click(Sender: TObject);
begin
ClntComObj:=CoTest2.Create;
ClntComObj.TestProc('!!!');
end; Кусок из кода, созданного мастером:
ITest2 = interface(IUnknown)
['']
function TestProc(const str: WideString): HResult; stdcall;
end;
CoTest2 = class
class function Create: ITest2;
class function CreateRemote(const MachineName: string): ITest2;
end;
implementation
uses ComObj;
class function CoTest2.Create: ITest2;
begin
Result := CreateComObject(CLASS_Test2) as ITest2;
end;
class function CoTest2.CreateRemote(const MachineName: string): ITest2;
begin
Result := CreateRemoteComObject(MachineName, CLASS_Test2) as ITest2;
end;
Сама реализация на сервере:
type
TTest2 = class(TTypedComObject, ITest2)
public
function TestProc(const str: WideString): HResult; stdcall;
end;
implementation
uses ComServ;
function TTest2.TestProc(const str: WideString): HResult;
begin
ShowMessage('TestProc (ComSrv): '+str);
Result:=S_OK;
end;
initialization
TTypedComObjectFactory.Create(ComServer, TTest2, Class_Test2,
ciMultiInstance, tmApartment);
end.
Теперь при вызове в клиенте: ClntComObj:=CoTest2.Create; при незапущенном сервер получаю ошибку Класс не зарегестрирован - все правильно. Запускаю ехе с сервером, запускаю клиента, жму кнопку, получаю исключение Interface not supported. Где косяк? В книжке типа все работает.
-
> Где косяк?
Первое что приходит в голову - декларации интерфейса ITest2 в части GUID в сервере и контроллере отличаются.
-
> ShowMessage('TestProc (ComSrv): '+str);
Так из COM лучше не надо. > procedure TForm1.Button1Click(Sender: TObject);begin //нужно > получить ссылку на объект //ComObj:=???? ClntComObj: > =CoTest2.Create; ClntComObj.TestProc('!!!');end;
Например, следующий код будет успешно откомпилирован, но при выполнении вызовет ошибку «Interface not supported»:
var
Test: ITest;
begin
Test := TInterfacedObject.Create as ITest;
Test.Beep;
end;
В то же время код
var
Test: ITest;
begin
Test := TTest.Create as ITest;
Test.Beep;
end;
будет успешно компилироваться и выполняться.
Читай КОРАН до конца. Из твоей же ссылки выдрано.
-
> Первое что приходит в голову - декларации интерфейса ITest2 > в части GUID в сервере и контроллере отличаются.
Как они могут отличаться, когда используют общую библиотеку типов, где ITest2 и объявлен:
unit COMSrv_TLB;
ITest2 = interface(IUnknown)
['']
function TestProc(const str: WideString): HResult; stdcall;
end;
-
> Читай КОРАН до конца. Из твоей же ссылки выдрано.
Не понял. У нас есть библиотека типов для использования в клиенте (созданная мастером) - COMSrv_TLB. Все что у нас там есть - это CoTest2 = class
class function Create: ITest2;
class function CreateRemote(const MachineName: string): ITest2;
end; и
ITest2 = interface(IUnknown)
['']
function TestProc(const str: WideString): HResult; stdcall;
end;
Где я недопонял? TTest2 в этом модуле не значится. Да и вроде не нужен он, для этого у нас есть ITest2. В приведенном выше примере из книги показана проблема с вызовом из родительского класса, у меня он вообще один.
-
И все таки не понятно, почему из самого сервера все работает, а из другого процесса Interface not supported?
-
> OleAutomation
Пересоздай СОМ-сервер, убрав в визарде крыжик "Make Interface OleAutomation"
-
> Пересоздай СОМ-сервер, убрав в визарде крыжик "Make Interface > OleAutomation"
Не помогло. Все также - из самого процесса сервера все ок, а из другого - Interface not supported. Также возникает вопрос - почему при незапущенном процессе сервера клиент выдает Класс не зарегистрирован? Судя по книжке при первом запуске сервера тот должен зарегистрировать свой ком объект в реестре в разделе CLSID. За это вроде бы отвечает код: TTypedComObjectFactory.Create(ComServer, TTest, Class_Test,
ciMultiInstance, tmApartment); Но в реестре ничего не нахожу ни во время работы сервера (непонятно тогда как клиент его вообще находит?), ни после.
-
> Судя по книжке при первом запуске сервера тот должен зарегистрировать > свой ком объект в реестре в разделе CLSID
Совершенно верно. И не только там.
Попробуй промониторить обращения твоего СОМ-сервера при старте к реестру на предмет регистрации. Средством для мониторинга можно выбрать, например, RegMon от sysinternals.com
-
> Совершенно верно. И не только там. > > Попробуй промониторить обращения твоего СОМ-сервера при > старте к реестру на предмет регистрации. Средством для мониторинга > можно выбрать, например, RegMon от sysinternals.com
Попробовал. Нету там обращений к HKCR\CLSID как это должно быть по книжке (потому и не нахожу там ничего). Зато есть 618.06370894 COMSrv.exe:3452 OpenKey HKCU\CLSID\{4E06D1B4-0310-42FD-B72E-9ABE9B4F4D4B} NOTFOUND
Такого раздела нет вообще!
Я совсем в ступоре.
-
>Запускаю ехе с сервером, запускаю клиента, жму кнопку, получаю исключение Interface not supported.
У тя регистрация сервака не прошла. Первый раз его нать под админом запустить, а то прав на реестр не хватит.
А флажок OleAutomation верни, без него точно работать не будет. Ток сначала запусти сервак с ключом /UNREGSERVER (на всяк случай:)), потом верни флажок, пересобери, и запусти с флажком OleAutomation. Оба запуска - под админом.
-
> У тя регистрация сервака не прошла. Первый раз его нать > под админом запустить, а то прав на реестр не хватит. > > А флажок OleAutomation верни, без него точно работать не > будет. Ток сначала запусти сервак с ключом /UNREGSERVER > (на всяк случай:)), потом верни флажок, пересобери, и запусти > с флажком OleAutomation. Оба запуска - под админом.
Хыхы, блин. Все всегда под админом делал. Что сделал сейчас. Для старого сервера выполнил /unregserver. Пересоздал с включенным крыжыком OleAutomation. И знаете что помогло? Запуск ComSrv.exe /regserver !!! Почему про это нигде не написано??? Типа все само зарегится. Не регилось. Теперь из клиента все пашет, при вызовепроцедуры запускается приложение сервера (вместе с формой) и все работает.
Для тестов еще раз сделал /unregserver, запустил сервер - не появилось в реестре ничего. Сделал снова /regserver - все снова появилось. Книжка врет? Или я че то не догоняю? Вот, теперь остается вопрос
-
>[Delphi, Windows] А ты в курсе, что и то и другое ваще-т разных версий бывают? Книжка не врет, как минимум по D7 включительно Exe-сервак при старте регится автоматом независимо от ключей. Че там дальше наворотили - не в курсях.
-
> Книжка не врет, как минимум по D7 включительно Exe-сервак > при старте регится автоматом независимо от ключей. Че там > дальше наворотили - не в курсях.
Делаю в делфи 2007. Может действительно в нем автоматическую регистрацию убрали?
Ладно. С этим разобралися. Теперь возвращаемся к вопросу передачи ссылки на объект, созданный на сервере к клиенту. В книжке этот вопрос не рассматривается.
-
> флажок OleAutomation верни, без него точно работать не будет
С какого перепугу ? олей-автоматизация автору нафих не нужна.
-
> Теперь возвращаемся к вопросу передачи ссылки на объект, > созданный на сервере к клиенту
Возвращаемся. Но прежде всего уточни, а устраивает ли тебя такая схема - процесс сервера стартует лишь по запросу клиента ?
-
>С какого перепугу ? олей-автоматизация автору нафих не нужна.
Да? А кто тады маршалингом заниматься будет? Автоматизация не нужна, оле-совместимость нужна. Дык автоматизация - Dual.
-
>Теперь возвращаемся к вопросу передачи ссылки на объект, созданный на сервере к клиенту.
Нифига не возвращаемся. Ты про какие объекты толкуешь, про дельфийские что-ли? И че клиент будет делать с указателем на ВАП чужого процесса? Лучше вернись к вопросу организации памяти в винде.
-
> кто тады маршалингом заниматься будет?
Маршаллингом будет заниматься прокси на стороне контроллера и стаб на стороне сервера.
-
> Возвращаемся. > Но прежде всего уточни, а устраивает ли тебя такая схема > - процесс сервера стартует лишь по запросу клиента ?
Когда я разберусь с передачей ссылки, тогда и буду все это встраивать в службу (service). Ну или еще что то придумаю. Сейчас для меня главное разобраться в технологии COM. Вернее сказать служба у меня уже есть, я к ней хочу прикрутить доступ через COM (ну к объекту в этой службе)
-
> ага (02.04.08 13:25) [31]
> про какие объекты толкуешь, про дельфийские что-ли?
Не придирайся. Понятно же, что на COM-интерфейсные.
Лучше посоветуй автору отказаться от COM/DCOM и регистрируемых в реестре серверов в пользу собственноручно выбранного транспорта (сокеты, пайпы - это уж на вкус выбирать), контролируемого маршаллинга (а-ля sconnect) и нерегистрируемых internal-серверов.
-
> служба у меня уже есть, я к ней хочу прикрутить доступ через > COM
Тогда стандартный визард тебе не подойдет.
-
> Тогда стандартный визард тебе не подойдет.
Почему не подойдет? От такого ком объекта нельзя передавать ссылки?
-
-
>Маршаллингом будет заниматься прокси на стороне контроллера и стаб на стороне сервера.
Во как:) А откуда они возьмутся?
-
-
>Лучше посоветуй автору отказаться от COM/DCOM и регистрируемых в реестре серверов в пользу собственноручно выбранного транспорта (сокеты, пайпы - это уж на вкус выбирать), контролируемого маршаллинга (а-ля sconnect) и нерегистрируемых internal-серверов.
Не, эт я советовать не буду, потому как несогласный я:))
-
> откуда они возьмутся?
А мы работы не боимся - мы сами напишем и прокси и стаб)
К тому же, плясать под дудку стандартного олей-маршаллинга не всегда удобно и возможно - приходится действовать с постоянной оглядкой на допустимые в олей-автоматизации типы данных, что порой добавляет не меньшую головную боль, чем написание специфичного для конкр.задачи маршаллера.
-
> несогласный я
Ну что ж) Насиловать тебя мы тож не вправе) Несогласный знач несогласный)
А по мне так оч даже приятственно не зависеть ни от каких реестров, стандартных проксей-заглушек и прочей шняги)
-
-
> > В помощь тебе: > > http://megalib.com/books/923/77715.htm
Спасибо конечно, но 1. У меня дома бумажный вариант этого дела 2. Читаем в конце (у меня в бумаге также): Нам остается лишь написать реализацию метода:
function TTest1.ShowIt(const S: WideString): HResult;
begin
MessageBoxW(0, PWideChar(S), NIL, 0)
Result := S_OK; end;
Для регистрации сервера достаточно один раз запустить его на компьютере клиента. Как показала практика не работает. Ну и собственно ни в моем бумажном варианте, ни в инете я пока так и не отыскал простого примера по передаче ссылки на объект в другой процесс.
-
>А мы работы не боимся - мы сами напишем и прокси и стаб)
Кто, автор вопроса? Который тока-тока начал ком осваивать? Не смешите мои тапочки. А нафига оно ему надо, когда стандартного за глаза?
>Не придирайся. Понятно же, что на COM-интерфейсные.
Да не придираюсь я ни разу, ей-ей. Он же книгу читает, че, там не написано, как интерфейсы передавать.
>_Z_ (02.04.08 14:46) [44] Упрямый ты. Ты пост [31] читал? Какие ты ссылки на объекты ты собрался передавать из одного процесса в другой, и че ты там собираешься делать. Либо отвечаешь на эти вопросы, либо дальше без меня.
>ни в моем бумажном варианте, ни в инете я пока так и не отыскал простого примера по передаче ссылки на объект в другой процесс.
Еще бы.
-
> _Z_ (02.04.08 14:46) [44] > >
> Как показала практика не работает
Что, и с ключем /regserver регистрация тоже не осуществляется ? А попытка-то хоть при этом есть, если наблюдать под монитором ?
> не отыскал простого примера по передаче ссылки на объект > в другой процесс
На какой такой "другой" ?
-
> че, там не написано, как интерфейсы передавать
Ну это был типа риторичесуий вопрос:))
> Какие ты ссылки на объекты ты собрался передавать из одного > процесса в другой, и че ты там собираешься делать.
А эт тож вопрос, тока не риторический.
-
> Кто, автор вопроса? Который тока-тока начал ком осваивать?
Именно поэтому я и предложил изучить механизм маршаллинга на примере sconnect.
-
Да нафига оно надо-то?!! Поставил флажок, рзарегил библиотеку типов - готово, имеешь маршалер. Свой городить имеет смысл, когда типы нестандартные, а тут-то нафига? Я вручную прокси-стаб делал, занетие - не для начинающих, однозначно. Лучше студию запустить и там сгенерить.
Но здесь-то, в этой ветки оно нафига???
> изучить механизм маршаллинга на примере sconnect
Да не маршалинг там, в sconnect:(( Так, бледная тень. Куча ограничений, недоделок, плюс глюки.
-
> рзарегил библиотеку типов
Да нафига оно надо-то, что-то там "регить" для узкоспецифической задачи ?)
Реестр и так переполнен хламом по самое нехочу, еще и свой хлам ради непонятной блажи ?)
-
> Свой городить имеет смысл, когда типы нестандартные
А вот с этого и надо было автору начинать)
Мож он какой-нить TMyComponent в оригинальноq его ипостаси собрался туда-сюда гонять)
-
> Куча ограничений, недоделок, плюс глюки
Все это легко снимается, дорабатывается и устраняется. Взамен получаем маршаллер, заточенный под любой свой каприз)
-
> здесь-то, в этой ветки оно нафига?
В вопросе, вообще-то, ни СОМ ни OLE не фигурировал.
Речь шла просто о некоем маршаллинге.
-
2 Сергей М
Лана, с этим, считаем, разобрались. Вертаемся к вопросу:)
2 _Z_
> Ищется пример передачи ссылки на созданный объект (интерфейс) > в другой процесс. Что то сам не осилил пока.
Дык всеж-таки - объект или интерфейс? Разницу асися? И че, в книге нет примера передачи интерфейса?! Я ее канечна не читал, но чет не верится. Хотя мож и нет, вещь-то самоочевидная. добавь в метод сервера out или var параметр типа интерфейс и возвращай на здоровье. Но - интерфейс!, не объект!
-
> Дык всеж-таки - объект или интерфейс? Разницу асися? И че, > в книге нет примера передачи интерфейса?! Я ее канечна > не читал, но чет не верится. > Хотя мож и нет, вещь-то самоочевидная. добавь в метод сервера > out или var параметр типа интерфейс и возвращай на здоровье. > Но - интерфейс!, не объект!
Не интерфейс, объект. Создаем на сервере:
Obj:=IComObj.Create
А в клиенте хочу не создавать свой, а использовать созданный на сервере.
Можно ли так сделать?
Идея - организовать вывод на форму приложения фрейм (или даже всю форму) из службы. Может конечно я не с того конца подступился... Может и не надо так делать. Может правильнее создавать объект из клиента, а уже при создании запуститься служба и через этот объект мы сможем вытягивать необходимые данные от службы?
-
> Может правильнее создавать объект из клиента, а уже при > создании запуститься служба и через этот объект мы сможем > вытягивать необходимые данные от службы?
Именно так.
-
> Можно ли так сделать?
Нет, нельзя. Опять возвращаемся к тому-же - к организации памяти в Windows. И к понятию "виртуальное адресное пространство процесса"
> Obj:=IComObj.Create
Это ваще че такое? Кто такой IComObj? Класс? Кокласс? Create - это что? Конструктор? Функция? Если функция, какой тип возвращает?
Послушай совета - нэ делай сервиса, нэ нада:(
-
> > Может правильнее создавать объект из клиента, а уже при > > > создании запуститься служба и через этот объект мы сможем > > > вытягивать необходимые данные от службы? > > > Именно так.
Ладно, с этим выяснил. Создаю в службе COM сервер, который запустится при запросе клиентом. По сколько ком сервер выполняется в адресном пространстве службы, то он имеет полный доступ к данным этой службы и значит через методы ком сервера можно вытягивать простые типы данных, совместимые с моделью ком? А можно ли тянуть "сложные" данные? Ну к примеру, хочу вытягивать структуры.
-
> хочу вытягивать структуры
Без проблем. Опиши структура в библилтеке типов и создай метод, возвращающий параметр типа этой структуры. Не пройдет для массива структур.
-
> А можно ли тянуть "сложные" данные? Ну к примеру, хочу вытягивать > структуры
Можно тянуть сто угодно. Но пока не видно повода городить огород с COM.
Если все же огород нужен, то делается он по иной схеме: реализуется InProc COM-сервер, который собссно осуществляет инф.обмен с процессом сервиса с использованием любой иной утилитарной коммуник.технологии: сокеты, пайпы, MMF, thread-сообщения...
-
> делается он по иной схеме
Кем? И чем оно будет лучше нормального COM?
-
> Кем?
Мной)
Устраивает ?) Думаю, нет. Примеры ? Их навалом. Возьми, к примеру, Скайп. Не ищи там сервис - его нет, но схема именно такая.
> чем оно будет лучше нормального COM?
А чем InProc-сервер "ненормальней" OutProc-сервера ?)
-
>Устраивает ?) Думаю, нет.
Почему?! Наоборот - как раз совершенно устраивает. Тока и надоть было сразу написать - типа "я, опираясь на свой опыт, предпочитаю делать так, а не иначи". Нормальный аргумент. А так получилось типа "вот он, единственно правильный способ, все конкретные пацаны делают тока так, и не иначе, а все остальное ацтой и сукс". А оно как бы не совсем так, ага?
|