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

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

Ошибка вызова процедуры COM-сервера [D6, Win2k]


DmitryMN ©   (2002-09-05 13:38:00) 

2. Почему если я вызываю сервер через Variant, и результат функции присваиваю
какой-нибудь переменной, происходит ошибка Invalid Callee:

var
V:Variant;
d:double;
begin
V:=CreateOleObject("MemoSrv.MemoIntf");
d:=V.GetNumber;
end;

Однако при вызове процедуры такого не происходит.
Сервер внешний, поддерживает IDispatch.


DmitryMN   (2002-09-06 11:48:00) [1]

To Набережных С.:

Кстати в заголовке функции GetNumber должно быть так

function GetNumber( Value: double): HResult; stdcall;

или так

function GetNumber( out Value: double): HResult; stdcall;



DmitryMN   (2002-09-06 11:22:00) [2]

Спасибо - все заработало:)


Набережных С.   (2002-09-05 19:40:00) [3]


> function GetNumber(out Result double): HResult; stdcall;

:))))
Только сейчас обратил внимание, надо было так подправить:
function GetNumber( Value: double): HResult; stdcall;


Набережных С.   (2002-09-05 19:14:00) [4]

Даже не знаю, с чего начать :) SafeCall - чисто дельфийская обертка-декларация. Она заставляет компилятор сгенерить в сервере нечто вроде этого(в первом приближении):

function GetNumber(out Result double): HResult; stdcall;
begin
try
//твой код
Result:=0;
except
on E:EOleException do Result:=E.ErrorCode;
else Result:=E_UNEXPECTED;
end;
end;

хотя в исходном коде у тебя он описан так:

function GetNumber: Double;
begin
//твой код
end;

А описание в IDL - это то, как метод описан в библиотеке типов, т.е. как он РЕАЛЬНО реализован в исполняемом коде.
Соглашение-же о безопасном вызове требует, что-бы любой метод в Automation возвращал hresult. И хотя это не жестко обязательно, однако VB, например, может работать только с такими методами.
Ну а SafeCall - это для нашего всеобщего удобства только :).


Digitman   (2002-09-05 18:52:00) [5]

А как тогда понять несоответствие

IDL: id(0x00000002)
TLB: dispid 5;

???


DmitryMN   (2002-09-05 18:29:00) [6]

Так ведь safecall и обеспечивает то что функция записанная как

function GetNumber: Double; safecall;

будет воспринята как

function GetNumber(out Result double): HResult; stdcall;

Она ведь работает при вызове сервера из интерфейса, а при вызове из variant - нет


Набережных С.   (2002-09-05 18:23:00) [7]


> DmitryMN (05.09.02 16:51)

Не, брат, что-то не похоже на SafeCall. В IDL он должен выглядеть примерно так:

[
id(0x00000002)
]
hresult _stdcall GetNamber([out, retval] double * Value );

Что-то ты где-то напортачил. Попробуй удалить и заново объявить его в библиотеке типов. Только удали его и в классе.


DmitryMN   (2002-09-05 18:14:00) [8]

IMemoIntfDisp = dispinterface
["{0D7215D9-1DBC-4571-AE89-159984AD85B0}"]
function GetNumber: Double; dispid 5;
end;


Digitman   (2002-09-05 17:55:00) [9]

приведи соответствующее объявление в MemoSrv_TLB.pas
IMemoIntfDisp = dispinterface
... ???
end;


DmitryMN   (2002-09-05 16:51:00) [10]

Методобъявлен как safecall

Объявление метода в TMemoIntf:

function TMemoIntf.GetNumber: Double;
begin
Result:=FNumber;
end;

и в IDL:
[
id(0x00000002)
]
double _stdcall GetNumber( void );


Digitman   (2002-09-05 16:12:00) [11]

Метод объявлен как safecall ?


Набережных С.   (2002-09-05 15:56:00) [12]

Покажи объявление метода в TMemoIntf и, желательно, в IDL.


DmitryMN   (2002-09-05 14:20:00) [13]

V:=CreateOleObject("MemoSrv.MemoIntf") - сервер создается - он появляется на экране и можно выполнить любую его процедуру, однако - когда дело доходит до функций - тут и возникает эта ошибка
d:=V.GetNumber - да - метод объявлен в интерфейсе MemoIntf.
Объект поддерживает этот интерфейс:
TMemoIntf = class(TAutoObject, IMemoIntf),
и сам метод GetNumber реализован в этом объекте.


Digitman   (2002-09-05 14:12:00) [14]

V:=CreateOleObject("MemoSrv.MemoIntf"); // ты уверен, что V not is Null после выполнения этой строчки ?

d:=V.GetNumber; // ты уверен, что объект поддерживает данный метод ?


DmitryMN   (2002-09-05 14:06:00) [15]

Побовал - тот же эффект


Eduard   (2002-09-05 13:55:00) [16]

По всей видимости, переменная d должна иметь тип OleVariant


Наверх

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