Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Corba";
Текущий архив: 2007.02.18;
Скачать: [xml.tar.bz2];

Вниз

DCOM. Ошибка: Интерфейс не поддерживается.   Найти похожие ветки 

 
Артем Кудлаекно   (2005-10-18 12:59) [0]

library CalcSubscription;

uses
 ComServ,
 ComObj,
 MyCalc_TLB in "MyCalc_TLB.pas",
 Unit1 in "Unit1.pas" {Calc: CoClass};

exports
 DllGetClassObject,
 DllCanUnloadNow,
 DllRegisterServer,
 DllUnregisterServer;

{$R *.TLB}

{$R *.RES}

begin
end.


unit MyCalc_TLB;

{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface

uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;

const
 MyCalcMajorVersion = 1;
 MyCalcMinorVersion = 0;

 LIBID_MyCalc: TGUID = "{6C701D29-BF27-4B10-9139-B94F410CB5C2}";

 IID_ICalc: TGUID = "{FD810922-1BDB-48D1-93D3-65E584854C6E}";
 CLASS_Calc: TGUID = "{9D5C87A5-8BE2-40D8-B4C0-391D201F9B87}";
type

 ICalc = interface;

 Calc = ICalc;

 ICalc = interface(IUnknown)
   ["{FD810922-1BDB-48D1-93D3-65E584854C6E}"]
   function DoSomethind(as_text: OleVariant): HResult; stdcall;
 end;

 CoCalc = class
   class function Create: ICalc;
   class function CreateRemote(const MachineName: string): ICalc;
 end;

implementation

uses ComObj;

class function CoCalc.Create: ICalc;
begin
 Result := CreateComObject(CLASS_Calc) as ICalc;
end;

class function CoCalc.CreateRemote(const MachineName: string): ICalc;
begin
 Result := CreateRemoteComObject(MachineName, CLASS_Calc) as ICalc;
end;

end.


unit Unit1;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
 Windows, ActiveX, Classes, ComObj, MyCalc_TLB, StdVcl, Dialogs;

type
 TCalc = class(TTypedComObject, ICalc)
 protected
   function DoSomethind(as_text: OleVariant): HResult; stdcall;
   {Declare ICalc methods here}
 end;

implementation

uses ComServ;

function TCalc.DoSomethind(as_text: OleVariant): HResult;
begin
ShowMessage(as_text);
Result := S_OK;
end;

initialization
 TTypedComObjectFactory.Create(ComServer, TCalc, Class_Calc,
   ciMultiInstance, tmApartment);
end.


Код в приложении рабочий:
procedure TForm1.Button2Click(Sender: TObject);
var Calc:ICalc;
 begin
 Calc := CoCalc.Create;
 Calc.DoSomethind("Test");
end;


Код в приложении не рабочий:
procedure TForm1.Button3Click(Sender: TObject);
var Calc:ICalc;
begin
  Calc := CoCalc.CreateRemote("localhost");
  Calc.DoSomethind("Remote is good!");
end;


CalcSubscription.dll скопировал в C:\Windows\System32.
Вызвал regsvr32 CalcSubscription.dll.
При вызове CreateRemote("localhost") в процессах появляется dllhost.
В dcomcnfg нашел свой GUID и дал всем все права.

Что я еще не сделал?


 
isasa ©   (2005-10-18 13:26) [1]

У DLL нет своего адресного пространства, поэтому она просто так DCOM не будет.
См. MSDN, ключевые слова Surrogate Sharing, DllSurrogate


 
Артем Кудлаенко ©   (2005-10-18 14:19) [2]

Получается, мне необходимо реализовать еще одну DLL: proxy/stub?
Я могу этого всего избежать, если сервер будет реализован в виде исполняемого файла?


 
isasa ©   (2005-10-18 14:50) [3]

По идее, да.

CLSCTX_REMOTE_SERVER    = 16 (*.exe)


 
Набережных С. ©   (2005-10-18 17:18) [4]

>Артем Кудлаенко ©   (18.10.05 14:19) [2]
>Получается, мне необходимо реализовать еще одну DLL: proxy/stub?

Не обязательно. В данном случае

ICalc = interface(IUnknown)
  ["{FD810922-1BDB-48D1-93D3-65E584854C6E}"]
  function DoSomethind(as_text: OleVariant): HResult; stdcall;
end;

в качестве proxy/stub может быть использован универсальный маршалер из oleaut32.dll, так как в методе интерфейса все параметры OleAutomation - совместимые.

>Я могу этого всего избежать, если сервер будет реализован в виде исполняемого файла?

Нет, proxy/stub необходимы. proxy/stub служат как раз для упаковки/распаковки параметров вызовов в вид, пригодный для передачи между процессами и машинами. Если клиент и сервер находятся в разных процессах, то пара proxy/stub необходима.


 
isasa ©   (2005-10-18 17:43) [5]

Не надо пугать человека.
Естественно маршаллинг(proxy/stub) будет.
Но писать самому его не придется.


 
Набережных С. ©   (2005-10-18 18:35) [6]


> isasa ©   (18.10.05 17:43) [5]


> Не надо пугать человека.

Да, не придется - если будет использован универсальный маршалер из Oleaut32, как уже было сказано выше. Сам факт размещения сервера в exe-файле вовсе этого не гарантирует. В exe-сервере прекрасным образом могут располагаться объекты, реализующие не совместимые с оле интерфейсы, либо эти интерфейсы могут быть не помечены как OleAutomation, либо для них может не быть библиотеки типов - все эти варианты вполне допустимые, но только тогда потребуется иметь proxy/stub для каждого из реализованных в сервере интерфейсов, с которым предполагается работа клиентов.

Так что не надо путать человека.


 
Набережных С. ©   (2005-10-18 18:43) [7]

И еще, разумеется, не придется писать Proxy/Stub для тех интерфейсов, для которых proxy/stub уже кем-то написаны и имеются в системе, например большинство определенных в системе интерфейсов - ну это, думаю, вполне очевидно.


 
Артем Кудлаенко ©   (2005-10-18 21:02) [8]

Спасибо за разъяснения.
На данный момент меня proxy/stub пугает. И путаюсь немного тоже :)

Я сделал сервер в виде исполняемого файла. Все заработало.

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

2. Если я правильно понял, когда я буду использовать в параметрах методов типы не совместимые с OleAutomation, то мне прийдется писать свой proxy/stub?

3. Почему возникала ошибка "Interface not supported" пока я не зарегистрировал сервер на машине клиента?

4. Почему сервер выполнял недопустимую операцию, пока я не сменил учетную запись с которой запускается сервер с "Запускающего пользователя" на "Текущего пользователя"?

5. Когда я проверял эмпирическим путем какие права нужны для того, чтобы клиенты могли вызывать сервер, я запретил доступ всем. Теперь из dcomcnfg пропал мой сервер и я не могу вернуть все обратно. В реестре, естественно, не могу удалить все ветки с моим GUID`ом. Как можно вернуть все "на родину"?


 
isasa ©   (2005-10-18 21:58) [9]

Если без глубокой теории:
1. Да (в разных адресных пространствах)
2. Да. (поэтому этого лучше не делать). Если сильно приспичит передать, что-нибудь не OLE, например, record, пакуй ее в VarArray.
3. Proxy-часть маршалинга встроена в сервер.
4. Не знаю.
5. Попробуй вернуть права через Владелец (Кнопка Дополнительно).
Еще, мастер прототипом ставит(в D7) TAutoObject
TCalc = class(TAutoObject, ICalc) ????


 
Артем Кудлаенко ©   (2005-10-18 22:14) [10]


> TCalc = class(TAutoObject, ICalc) ????


TCalc = class(TTypedComObject, ICalc)

И сейчас(после того как перевел сервер на исполняемый) в параметре метода тип         не OleVariant, а WideString(Я все делал с помощью мастера и выбрал для метода тип BSTR)


 
isasa ©   (2005-10-18 22:33) [11]

WideString в *_TLB.pas - нормально.
См. View -> Type library -> тыкни на методе -> см. закладку Text


 
Набережных С. ©   (2005-10-19 12:04) [12]


> isasa ©   (18.10.05 21:58) [9]
> 3. Proxy-часть маршалинга встроена в сервер.

Ну откуда такие фантазии?:( Я ж сказал - OleAut32...

> Артем Кудлаенко ©   (18.10.05 21:02) [8]


> 4. Почему сервер выполнял недопустимую операцию, пока я
> не сменил учетную запись с которой запускается сервер с
> "Запускающего пользователя" на "Текущего пользователя"?

Универсальному маршалеру на клиенте для правильной организации маршилинга вызовов требуется информация о типах параметров методов и о способе их передачи. Такая информация находится в библиотеке типов сервера и именно эта библиотека и необходима на клиенте. Когда ты на клиенте зарегистрировал сервер, то он автоматически зарегистрировал и свою библиотеку типов, поэтому и заработало. Хотя на клиенте регистрировать сервер нет необходимости, достаточно скопировать туда и зарегистрировать файл *.TLB.

> 4. Почему сервер выполнял недопустимую операцию, пока я
> не сменил учетную запись с которой запускается сервер с
> "Запускающего пользователя" на "Текущего пользователя"?

Вероятно, на компьютере сервера у клиента нет прав. Нужно дать права учетке клиента на сервере. Но лучше все-же установить запуск сервера от конкретной специально созданной учетной записи или от LocalSystem. Почему долго объяснять, а у меиня нет времени, поищи в инете есть.

> 5. Когда я проверял эмпирическим путем какие права нужны
> для того, чтобы клиенты могли вызывать сервер, я запретил
> доступ всем. Теперь из dcomcnfg пропал мой сервер и я не
> могу вернуть все обратно. В реестре, естественно, не могу
> удалить все ветки с моим GUID`ом. Как можно вернуть все
> "на родину"?

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


 
Артем Кудлаенко ©   (2005-10-19 15:41) [13]

Прочитал в справке, что массивы должны передавать через специальный тип называемый SafeArray. Я выбераю этот тип через окно мастера Type Library (SAFEARRAY(long))и у меня в параметр метода подставляется тип PSafeArray без указания типа(of long).
Как работать с массивами(двухмерными тоже)? Тип элементов я должен указать в скобках? На пример: SAFEARRAY(double)
Так же в справке написано(если я правльно понял), что в *_TLB модуле не отображается тип элементов.


 
Набережных С. ©   (2005-10-19 17:50) [14]

Дельфи умеет работать только с SafeArray of integer. И, кстати, в большинстве случаев удобнее иметь дело с OleVariant, чем напрямую с pSafeArray.

Для передачи массива записей существует несколько способов - через VarArrayCreate etc, через интерфейс-перечислитель, через объект, маршалируемый по значению. выбор зависит от условий задачи и от типов данных в записи.

ЗЫ Вопрос вышел за тему этой ветки, а в таких случаях принято создавать новые ветки.



Страницы: 1 вся ветка

Форум: "Corba";
Текущий архив: 2007.02.18;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.04 c
2-1170244505
ACSBaks
2007-01-31 14:55
2007.02.18
Не работает JEDI API Library!!


15-1169918975
Zeqfreed
2007-01-27 20:29
2007.02.18
Кто желал голосовой поисковик музыки?


1-1167225169
DVM
2006-12-27 16:12
2007.02.18
Отловить изменение числа мониторов. Проблема.


15-1170150334
legat
2007-01-30 12:45
2007.02.18
Ручная вставка в TDBGridEh


2-1169971490
LiteStone
2007-01-28 11:04
2007.02.18
Глюк





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский