Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];

Вниз

procedure of class?   Найти похожие ветки 

 
Sandman25   (2004-05-20 10:38) [0]

Доброе время суток.

Подскажите, пожалуйста, как можно заменить объявление
Type
 TEntityProcedure = procedure (...) of object
чтобы использовать не обычные методы, а "классовые"
class procedure (...)

EntityClassFor(CashData).CallProcAndKeepContext(EntityProcedureFor(CashData), ...)

EntityClassFor возвращает TEntityClass = class of TEntity
EntityProcedureFor возвращает TEntityProcedure
Внутри CallProcAndKeepContext происходит использование "классовых" методов для сохранения/восстановления контекста и между ними вызывается процедура, передаваемая параметром.
Спасибо.


 
Sandman25+1   (2004-05-20 10:44) [1]

Только что проверил в тестовом приложении... Вроде бы никакой разницы нет. Вопрос снимается.
Хотя в реальном приложении access violation происходит именно при вызове метода, переданного параметром и параметр вроде правильный. Буду разбираться.


 
Тимохов ©   (2004-05-20 10:45) [2]

вообще говоря, это прекрасно работает.
в чем проблема?

type
  TCls = class
     class procedure a;
  end;
 TProc = procedure of object;

class
procedure TCls.a;
begin
  showmessage("a");
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  kProc: TProc;
begin
  kProc := TCls.a;
  kProc(); // display "a"
end;


 
Sandman25+1   (2004-05-20 11:10) [3]

Проблема действительно есть. Что-то я неправильно делаю, видимо.

type
 TCashData = (cdMotiveType
 //, ...
 );

 TEntityRecord = record
   EntityClass: TEntityClass;
   EntityProcedure: TEntityProcedure;
 end;

const
 EntityArr: array[TCashData] of TEntityRecord =
(
//    cdMotiveType,
   (EntityClass: TFormularEntity; EntityProcedure: TFormularEntity.Filter)
//, ...
)

function EntityClassFor(CashData: TCashData): TEntityClass;
begin
 Result := EntityArr[CashData].EntityClass;
end;

function EntityProcedureFor(CashData: TCashData): TEntityProcedure;
begin
 Result := EntityArr[CashData].EntityProcedure;
end;

class procedure TEntity.CallProcAndKeepContext(
 EntityProcedure: TEntityProcedure;
 FormatDataAdapter: TFormatDataAdapter);
var
 OldFilterArr: array of String;
 Index: Integer;
begin
 SetLength(OldFilterArr, GetDataSetCount);
 for Index := Low(OldFilterArr) to High(OldFilterArr) do
   OldFilterArr[Index] := TDataSetAdapter.GetOldFilterAndDisableControls(GetDataSet(FormatDataAdapter, Index));
 try
   EntityProcedure(FormatDataAdapter);
 finally
   for Index := Low(OldFilterArr) to High(OldFilterArr) do
     TDataSetAdapter.SetOldFilterAndEnableControls(GetDataSet(FormatDataAdapter, Index), OldFilterArr[Index]);
 end;
end;

Так вот при вызове
   EntityClassFor(CashData).CallProcAndKeepContext(EntityProcedureFor(CashData), FormatDataAdapter);

Я попадаю в TFormularEntity.CallProcAndKeepContext, как и ожидается.
Но в Watch я вижу:
EntityArr[cdmotivetype],r: (EntityClass:TEntityClass($1BB10F0); EntityProcedure:$1BB10A4)
@entityprocedure: $1BB10F0
@tformularentity.filter: $1BB1B74
@tentity.filter: $1BB1B74

Получается, что параметр EntityProcedure указывает не на Tformularentity.filter, а на Tformularentity. Соответственно при вызове
   EntityProcedure(FormatDataAdapter) я получаю Access Violation, даже не заходя в TformularEntity.Filter.
Сообщение Write of address 01BB10B4.

Может, нужно инициализировать массив только в run-time?


 
Sandman25+1   (2004-05-20 11:18) [4]

Проблема похоже есть, причем в моем коде.
type
 TCashData = (cdMotiveType {, ...});

type
 TEntityRecord = record
   EntityClass: TEntityClass;
   EntityProcedure: TEntityProcedure;
 end;

const
 EntityArr: array[TCashData] of TEntityRecord =
   (
// формуляр
//    cdMotiveType,
   (EntityClass: TFormularEntity; EntityProcedure: TFormularEntity.Filter) {,...}
   );

function EntityClassFor(CashData: TCashData): TEntityClass;
begin
 Result := EntityArr[CashData].EntityClass;
end;

function EntityProcedureFor(CashData: TCashData): TEntityProcedure;
begin
 Result := EntityArr[CashData].EntityProcedure;
end;

class procedure TEntity.CallProcAndKeepContext(
 EntityProcedure: TEntityProcedure;
 FormatDataAdapter: TFormatDataAdapter);
var
 OldFilterArr: array of String;
 Index: Integer;
begin
 SetLength(OldFilterArr, GetDataSetCount);
 for Index := Low(OldFilterArr) to High(OldFilterArr) do
   OldFilterArr[Index] := TDataSetAdapter.GetOldFilterAndDisableControls(GetDataSet(FormatDataAdapter, Index));
 try
   EntityProcedure(FormatDataAdapter);
 finally
   for Index := Low(OldFilterArr) to High(OldFilterArr) do
     TDataSetAdapter.SetOldFilterAndEnableControls(GetDataSet(FormatDataAdapter, Index), OldFilterArr[Index]);
 end;
end;

Так вот при вызове
  EntityClassFor(cdMotiveType).CallProcAndKeepContext(EntityProcedureFor(cdMotiveType),
я попадаю, как и ожидается в TformularEntity.CallProcAndKeepContext, но в Watch вижу странные вещи:

entityarr[cdmotivetype],r: (EntityClass:TEntityClass($1BB10F0); EntityProcedure:$1BB10A4)
@entityprocedure: $1BB10F0
@tformularentity.filter: $1BB1B74

То есть локальный параметр EntityProcedure <> entityarr[cdmotivetype].EntityProcedure
И потом получаю AV: write of address 01BB10B4

Может, нужно явно инициализировать массив, а не использовать const?


 
Sandman25+1   (2004-05-20 11:27) [5]

Все, решил :) Сделал инициализацию массива в initialization-секции и проблема исчезла. Const массив почему-то "дурковал" :(



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

Форум: "Основная";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.031 c
1-1084361111
новичок_из_сыктывкара
2004-05-12 15:25
2004.05.30
строку наоборот


14-1084050627
Petr V. Abramov
2004-05-09 01:10
2004.05.30
Про семафоры


6-1081950490
Yurec66
2004-04-14 17:48
2004.05.30
У кого в сети еще запущена моя программа


3-1084274477
bushmen
2004-05-11 15:21
2004.05.30
Знающим MySQL


14-1084428741
Knight
2004-05-13 10:12
2004.05.30
Кто знает Word? Сам редко с ним общаюсь...





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