Форум: "Основная";
Текущий архив: 2002.09.16;
Скачать: [xml.tar.bz2];
ВнизОшибка вызова процедуры 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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c