Форум: "Основная";
Текущий архив: 2006.04.16;
Скачать: [xml.tar.bz2];
ВнизCOM-сервер и procedural var Найти похожие ветки
← →
tesseract © (2006-03-14 17:14) [0]Имеется такая тема (Com-сервер).
Объявлен родитель у которого имеется свойство TProcs:array of TCallProc;
TCallProc=procedure (var param:integer) of object;
При загрузке объекта массив соотвественно заполяется процедурами из класса наследника.
И всё ОК - за исключением того, что если попытаться вызвать из присвоенной процедуры какую либо процедуру или получить значение из класса-родителя, то AccessViolation.
Кто нибудь может помочь?
← →
clickmaker © (2006-03-14 17:56) [1]
> tesseract © (14.03.06 17:14)
пример кода с AV?
← →
tesseract © (2006-03-14 22:19) [2]
> пример кода с AV?
Да длинноват он. И AV я анализирую сам через try/except.
Как я понял при вызове процедуры я теряю поля объекта (как будто он не создан).
Но таблица методов остаётся нетронутой. Это и вызывает AV - как если бы я вызывал методы несозданного объекта.
Весело - методы теоретически должны входить в "рабочее пространство " объекта ибо там и объявлены.
← →
clickmaker © (2006-03-15 09:49) [3]
> при вызове процедуры я теряю поля объекта
так просто такого не бывает. значит где-то есть кривизна. Может объект и правда где-то случайно убивается
← →
tesseract © (2006-03-15 10:03) [4]
> так просто такого не бывает. значит где-то есть кривизна.
> Может объект и правда где-то случайно убивается
Вот в том-то и прикол. После того, как функция возвращает результат. То объект работает как ни в чём не бывало!
Возможно (я в Com я не очень силён), проблема в том что поля находяться в адресном простанстве клиента, а моя функция выполянется в пространстве сервера. Тогда возникает следующий вопрос - как эту функцию выполнить в контексте клиента?
AV вообще возникает весело - можно посмотреть как поля в памяти располагаются. Смещение AV всегда одно :-)
← →
clickmaker © (2006-03-15 10:07) [5]
> tesseract © (15.03.06 10:03) [4]
нужен все-таки пример кода.. По минимуму, только то, что относится к этим TCallProc
← →
tesseract © (2006-03-15 10:18) [6]Ну лови. В принципе присвоение:
описание структур
type TCallFunc=procedure( var paParams:Tparams; var retVal: OleVariant) of object;
type PCallProc= ^tCallProc;
// Пошли методы для добавления/ удаления методов
function TCustomAddIn.MethodAdd(nameeng, namerus: WideString;
ParamCount: integer; DefVals:Tparams;
CallProc:PCallProc;CallFunc:PcallFunc): boolean;
var CurDef:integer; // Для установки параметров по умолчанию
begin
{$IFDEF WITH_ADV_CHECKS}
ErrorLog("Adding "+namerus, logNone);
if (nameeng="") or (namerus="") then
begin
result:=false;
exit;
end;
if (not Assigned(CallProc)) and (not Assigned(CallFunc)) then
begin
result:=false;
exit;
end;
{$ENDIF}
try
fprocs[ProcCount].name[0]:=nameeng;
fprocs[ProcCount].name[1]:=namerus;
fProcs[ProcCount].ParamCount:=ParamCount;
if DefVals<>nil then
fprocs[ProcCount].NoDefParam:=false
else
fprocs[ProcCount].NoDefParam:=true;
@fprocs[ProcCount].CallProc:=CallProc;
@fProcs[procCount].CallFunc:=CallFunc;
if not fprocs[ProcCount].NoDefParam then
begin
SetLength(fprocs[ProcCount].DefParams,length(DefVals));
for CurDef:=0 to Length(DefVals)-1 do
begin
fprocs[ProcCount].DefParams[CurDef]:=DefVals[CurDef];
end;
end
else
fprocs[procCount].DefParams:=nil;
except
on E:Exception do MessageBox(0, PChar(E.message) , "Error", MB_ICONSTOP or MB_OK);
end;
Inc(ProcCount);
result:=true;
end;
Вызов функции - метод один в один:
// Если функция присвоена то выполняем
if assigned(fprocs[lMethodNum].CallFunc) then
begin
// Пробуем выполнить
try
Pars:=SafeArrayToParams(paParams,fProcs[lMethodNum].ParamCount);
fProcs[lMethodNum].CallFunc(Pars,pVarRetValue);
except
on E:Exception do MessageBox(0, PChar(E.message) , "Error", MB_ICONSTOP or MB_OK);
end;
result:=S_OK;
end
else
result := E_FAIL;
ErrorLog("Функция "+inttostr(lMethodNum)+" выполнена",logoRdinary);
Вызов AddMethod
TempFunc:=CallTest;
AddFunction("test","тест",2,@TempFunc);
procedure TCustomObject.CallTest( var paParams:Tparams; var retVal: OleVariant);
var i:integer;
tstr:Widestring;
begin
retval:="";
tstr:="";
// Вот эта функция объявлена в объекте
ErrorLog("Call test",logOrdinary);
// Если её не вызывать - всё ок иначе - AV. также со всеми полями
for i:=0 to length(paParams)-1 do
tstr:=tstr + "параметр" + inttostr(i) +" равен " + paparams[i] +#13#10;
retval:=tstr;
end;
← →
clickmaker © (2006-03-15 10:27) [7]а как ты собcсно вызываешь эту CallTest?
И TCustomObject и TCustomAddIn что за объекты?
← →
tesseract © (2006-03-15 10:31) [8]fProcs[lMethodNum].CallFunc(Pars,pVarRetValue); - вот и вызов CallTest.
TcustomAddIn - родитель в котором описаны интерфейсы и логика работы.
TcustomObject - наследник TCustomAddin. Перекрывает функцию инициализации и добавляет процедуры/функции в fproc[].CallProc/CallFunc.
ЗЫ: объекте >1500 строк.
← →
clickmaker © (2006-03-15 10:35) [9]
> tesseract © (15.03.06 10:31) [8]
> fProcs[lMethodNum].CallFunc(Pars,pVarRetValue); - вот и
> вызов CallTest
это изнутри. А с клиента как это выглядит? От создания объекта до вызова
← →
tesseract © (2006-03-15 10:44) [10]
> это изнутри. А с клиента как это выглядит? От создания объекта
> до вызова
Вот так и выглядит. Клиент передаёт название процедуры, Я нахожу его в массиве fprocs и вызываю.
← →
clickmaker © (2006-03-15 11:00) [11]
> tesseract © (15.03.06 10:44) [10]
т.е. создается объект типа TcustomObject, потом что-то типа
CO.CallMethod("CallTest")
?
← →
tesseract © (2006-03-15 11:06) [12]Да типа того, только + куча вспомогательных функций.
Для справки - это addin для 1c.
← →
clickmaker © (2006-03-15 11:30) [13]
> TcustomObject - наследник TCustomAddin. Перекрывает функцию
> инициализации
а как перекрывает? полностью или с вызовом inherited? Что там вообще инициализируется?
и AV только на ErrorLog или на любой функции предка?
← →
tesseract © (2006-03-15 12:31) [14]Функция объявлена как абстрактная. inherited там нет.
> и AV только на ErrorLog или на любой функции предка?
Не функции - при обращении к полям объекта из процедуры типа TCALLProc.
← →
clickmaker © (2006-03-15 12:54) [15]
> Вызов AddMethod
>
> TempFunc:=CallTest;
> AddFunction("test","тест",2,@TempFunc);
еще вот это место не совсем понятно... Зачем TempFunc?
как вообще заполняется массив функций? В конструкторе TCustomObject?
← →
tesseract © (2006-03-15 13:31) [16]Ладно сань, спасибо за помощь. Я разобрался. Надо было передавать ссылку на объект. Self почему-то не работал.
type TCallFunc=procedure(var obj; var paParams:Tparams; var retVal: OleVariant) of object;
И всё ок. Вызываешь метод объекта TCustomAddIn(obj).ErrorLog и всё :-)
Блин во гемор :-)
> еще вот это место не совсем понятно... Зачем TempFunc?как
> вообще заполняется массив функций? В конструкторе TCustomObject?
>
Массив функций заполняется в абстактной initModule, которая вызывается при инициализации объекта. TempFunc - я не могу передать указатель на функцию просто так, сначала нужно скопировать её адрес в переменную.
При выполнении AddProcedure произойдёт её dereference и всё ок.
Насколько я потрейсил - Create/destroy в TcomObject не вызывается. Их заменяют initialize/release.
← →
clickmaker © (2006-03-15 14:16) [17]вон оно как...
вообще странно. ErrorLog то хоть объявлена как virtual?
← →
tesseract © (2006-03-15 14:28) [18]
> вообще странно. ErrorLog то хоть объявлена как virtual?
А зачем? она преспокойно вызывается и так, только без полей.
В перекрытии она вообще-то и не нуждается. Это обёртка над IErrorLog.
← →
clickmaker © (2006-03-15 15:31) [19]
> TempFunc - я не могу передать указатель на функцию просто
> так
Да почему же?
насчет всего остального... Тут какая фигня с областями видимости переменных. Не знаю, не видя всего кода, трудно разобраться
← →
tesseract © (2006-03-15 16:10) [20]Да почему же?
Проверял :-) У меня много перегруженных функций, для заданий функций :-)
Пишет "Variable required".
> насчет всего остального... Тут какая фигня с областями видимости
> переменных. Не знаю, не видя всего кода, трудно разобраться
Это-то я понял. В отладчике прописано "inaccessable value". А не мусор, находимся то мы где положено, но на нас тоже положено. Возможно вмешивается "защитник" Delphi.
Причём не в COM такой код исполняется на ура.
← →
clickmaker © (2006-03-15 16:14) [21]
> Проверял :-) У меня много перегруженных функций, для заданий
> функций :-)
> Пишет "Variable required".
а зачем ты определяешь указатель на тип TCallProc?
просто
AddMethod(AProc: TCallProc)
← →
tesseract © (2006-03-15 16:43) [22]
> AddMethod(AProc: TCallProc)
Хм. Щас попробую, но помоему не срабатывало.
Тут ещё прикол. прописал переменную cont:TCustomObject вне определения класса. И знаешь - срабатывает:-)
Осталось выяснить что с ней делать. тк вылезает Oout of memory...
← →
tesseract © (2006-03-15 16:54) [23]Так cont начал работь и работать хорошо. Осталось выяснить будет ли на него обнуляться счётчик ссылок?
← →
tesseract © (2006-03-15 17:13) [24]Все Сань спасибо . Выяснилось, что как-раз таки из-за ссылок и пахалало.
А зачем использовал? Что-бы nil можно было передавать :-) и меньше функций переписывать :-)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.04.16;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.046 c