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

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

COM-сервер и procedural var [D7]


Страницы:   1 2

tesseract ©   (2006-03-14 17:14:00) 

Имеется такая тема (Com-сервер).

Объявлен родитель у которого имеется  свойство TProcs:array of TCallProc;

TCallProc=procedure (var param:integer) of object;

При загрузке объекта массив соотвественно заполяется процедурами из класса наследника.

И всё ОК - за исключением того, что если попытаться вызвать из присвоенной процедуры какую либо процедуру или получить значение из класса-родителя, то AccessViolation.

Кто нибудь может помочь?


tesseract   (2006-03-15 17:13:00) [1]

Все Сань спасибо . Выяснилось, что как-раз таки из-за ссылок и пахалало.
А зачем использовал? Что-бы nilможно было передавать :-) и меньше функций переписывать :-)


tesseract   (2006-03-15 16:54:00) [2]

Так cont начал работь и работать хорошо. Осталось выяснить будет ли на него обнуляться счётчик ссылок?


tesseract   (2006-03-15 16:43:00) [3]


> AddMethod(AProc: TCallProc)

Хм. Щас попробую, но помоему не срабатывало.

Тут ещё прикол. прописал переменную cont:TCustomObject вне определения класса. И знаешь - срабатывает:-)
Осталось выяснить что с ней делать. тк вылезает Oout of memory...


clickmaker   (2006-03-15 16:14:00) [4]


> Проверял :-) У меня много перегруженных функций, для заданий
> функций :-)
> Пишет "Variable required".

а зачем ты определяешь указатель на тип TCallProc?
просто
AddMethod(AProc: TCallProc)


tesseract   (2006-03-15 16:10:00) [5]

Да почему же?

Проверял :-) У меня много перегруженных функций, для заданий функций :-)
Пишет "Variable required".


> насчет всего остального... Тут какая фигня с областями видимости
> переменных. Не знаю, не видя всего кода, трудно разобраться

Это-то я понял. В отладчике прописано "inaccessable value". А не мусор, находимся то мы где положено, но на нас тоже положено. Возможно вмешивается "защитник" Delphi.
Причём не в COM такой код исполняется на ура.


clickmaker   (2006-03-15 15:31:00) [6]


> TempFunc - я не могу передать указатель на функцию просто
> так

Да почему же?

насчет всего остального... Тут какая фигня с областями видимости переменных. Не знаю, не видя всего кода, трудно разобраться


tesseract   (2006-03-15 14:28:00) [7]


> вообще странно. ErrorLog то хоть объявлена как virtual?

А зачем? она преспокойно вызывается и так, только без полей.

В перекрытии она вообще-то и не нуждается. Это обёртка над IErrorLog.


clickmaker   (2006-03-15 14:16:00) [8]

вон оно как...
вообще странно. ErrorLog то хоть объявлена как virtual?


tesseract   (2006-03-15 13:31:00) [9]

Ладно сань, спасибо за помощь. Я разобрался. Надо было передавать ссылку на объект. 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 12:54:00) [10]


> Вызов AddMethod
>
> TempFunc:=CallTest;
> AddFunction('test','тест',2,@TempFunc);

еще вот это место не совсем понятно... Зачем TempFunc?
как вообще заполняется массив функций? В конструкторе TCustomObject?


tesseract   (2006-03-15 12:31:00) [11]

Функция объявлена как абстрактная. inherited там нет.


> и AV только на ErrorLog или на любой функции предка?


Не функции  - при обращении к полям объекта из процедуры типа TCALLProc.


clickmaker   (2006-03-15 11:30:00) [12]


> TcustomObject - наследник TCustomAddin. Перекрывает функцию
> инициализации

а как перекрывает? полностью или с вызовом inherited? Что там вообще инициализируется?
и AV только на ErrorLog или на любой функции предка?


tesseract   (2006-03-15 11:06:00) [13]

Да типа того, только + куча вспомогательных функций.  
Для справки - это addin для 1c.


clickmaker   (2006-03-15 11:00:00) [14]


> tesseract ©   (15.03.06 10:44) [10]

т.е. создается объект типа TcustomObject, потом что-то типа
CO.CallMethod('CallTest')
?


tesseract   (2006-03-15 10:44:00) [15]


> это изнутри. А с клиента как это выглядит? От создания объекта
> до вызова

Вот так и выглядит. Клиент передаёт название процедуры, Я нахожу его в массиве fprocs и вызываю.


clickmaker   (2006-03-15 10:35:00) [16]


> tesseract ©   (15.03.06 10:31) [8]
> fProcs[lMethodNum].CallFunc(Pars,pVarRetValue); - вот и
> вызов CallTest

это изнутри. А с клиента как это выглядит? От создания объекта до вызова


tesseract   (2006-03-15 10:31:00) [17]

fProcs[lMethodNum].CallFunc(Pars,pVarRetValue);- вот и вызов CallTest.

TcustomAddIn - родитель в котором описаны интерфейсы и логика работы.

TcustomObject - наследник TCustomAddin. Перекрывает функцию инициализации и добавляет процедуры/функции в fproc[].CallProc/CallFunc.

ЗЫ: объекте >1500 строк.


clickmaker   (2006-03-15 10:27:00) [18]

а как ты собcсно вызываешь эту CallTest?
И TCustomObject и TCustomAddIn что за объекты?


tesseract   (2006-03-15 10:18:00) [19]

Ну лови. В принципе присвоение:
описание структур

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:07:00) [20]


> tesseract ©   (15.03.06 10:03) [4]

нужен все-таки пример кода.. По минимуму, только то, что относится к этим TCallProc


Страницы:   1 2

Наверх

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