Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.09.16;
Скачать: CL | DM;

Вниз

Ошибка вызова процедуры COM-сервера   Найти похожие ветки 

 
DmitryMN   (2002-09-05 13:38) [0]

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

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

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


 
Eduard ©   (2002-09-05 13:55) [1]

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


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

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


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

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

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


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

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


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

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


 
Digitman ©   (2002-09-05 16:12) [6]

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


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

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

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

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

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


 
Digitman ©   (2002-09-05 17:55) [8]

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


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

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


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


> DmitryMN (05.09.02 16:51)

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

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

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


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

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

function GetNumber: Double; safecall;

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

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

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


 
Digitman ©   (2002-09-05 18:52) [12]

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

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

???


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

Даже не знаю, с чего начать :) 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 - это для нашего всеобщего удобства только :).


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


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

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


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

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


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

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

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

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

или так

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





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

Текущий архив: 2002.09.16;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.013 c
14-50916
Мася
2002-08-21 09:11
2002.09.16
Автозагрузка


1-50712
reach
2002-09-02 12:41
2002.09.16
Как получить версию ActiveX компонента


6-50903
resident1984
2002-07-06 18:00
2002.09.16
NetBios имя хоста.


7-50984
Jorchick
2002-07-03 17:46
2002.09.16
Управление сервисами в Delphi


1-50858
Micah'GF
2002-09-04 09:27
2002.09.16
Как узнать из какого каталога запущена моя прога?