Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.042 c
15-1143085953
Pavluha
2006-03-23 06:52
2006.04.16
Компоненты XComm и XModem


15-1143037767
Харько
2006-03-22 17:29
2006.04.16
Задачка в среду


2-1143973368
MVP
2006-04-02 14:22
2006.04.16
Объясните пожалуйста как пользоваться scanline и region?


4-1138295443
Святослав
2006-01-26 20:10
2006.04.16
Как программно вызвать окно настройки шрифтов?


2-1143641950
001
2006-03-29 18:19
2006.04.16
Oracle server, client





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский