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

Вниз

Запись и вызов методов из массива   Найти похожие ветки 

 
Kostafey ©   (2006-12-12 19:30) [0]

Уважаемые мастера! Подскажите, пожалуйста. Записываю массив методов:

 TSQL_Keeper = procedure of object;

 TQParam = class(TObject)
 public
   SQL_Keeper:array[1..ABR_count] of TSQL_Keeper;
   ...
 published
   procedure SQL_a1;
   ...

Заполняю массив:

constructor TQParam.Create;
var i:byte;
   SQLName:shortstring;
begin
//Названия методов SQL_a1, SQL_a2,...
 for i:=1 to ABR_count do
 begin
   SQLName:="SQL_a"+inttostr(i);
   TMethod(SQL_Keeper[i]).Code:=TQParam.MethodAddress(SQLName);
   TMethod(SQL_Keeper[i]).Data:=TQParam;

Вызываю метод из массива:

function TQParam.QueryPrepare: boolean;
begin
 ...
 SQL_Keeper[1];


 
Джо ©   (2006-12-12 19:47) [1]

И в чем вопрос? Чем не устраивает

> SQL_Keeper[1];


 
Kostafey ©   (2006-12-12 19:55) [2]

> [1] Джо ©   (12.12.06 19:47)
> И в чем вопрос? Чем не устраивает
>
> > SQL_Keeper[1];

Ой, проблемы со связью ! Про главное не сказал:

SQL_Keeper[1]; - вызывает ошибку !!!


 
Джо ©   (2006-12-12 20:01) [3]

> [2] Kostafey ©   (12.12.06 19:55)
> > [1] Джо ©   (12.12.06 19:47)
> > И в чем вопрос? Чем не устраивает
> >
> > > SQL_Keeper[1];
>
> Ой, проблемы со связью ! Про главное не сказал:
>
> SQL_Keeper[1]; - вызывает ошибку !!!

И какую ошибку оно вызывает — это, конечно же, секрет. Или опять «проблемы со связью».


 
Kostafey ©   (2006-12-12 20:04) [4]

> И какую ошибку оно вызывает — это, конечно же, секрет. Или
> опять «проблемы со связью».


Access violation at address 00A74BDE in module "ABR.dll". Read of address 0600B77D.

Кстати, забыл сказать, что код выполняется в dll


 
Kostafey ©   (2006-12-12 21:55) [5]

SQL_Keeper[1];
Не работает при получении адресов методов:
@SQL_Keeper[i]:=TQParam.MethodAddress(SQLName);
или

TMethod(SQL_Keeper[i]).Code:=TQParam.MethodAddress(SQLName);
TMethod(SQL_Keeper[i]).Data:=TQParam;

Но вот так все работает:
SQL_Keeper[i]:=SQL_a1;


 
Джо ©   (2006-12-12 23:34) [6]

Код из [0] никакой ошибки не вызывает и работает отлично. Ищи в другом месте.


 
Kostafey ©   (2006-12-13 00:15) [7]

> Код из [0] никакой ошибки не вызывает и работает отлично.
> Ищи в другом месте.


Гм...гм... работает. и пустом проекте и в пустой dll (правда пробовал только неявную загрузку).

Может явная загрузка dll или использование ADO оказывает влияние ?
Ладно, спасибо, завтра устрою капитальное тестирование.


 
Kostafey ©   (2006-12-13 02:09) [8]

Наконец-то я готов задать проавильный вопрос !

Оказывается загвоздка заключается в полях класса, которые используются в адресуемом указателю методе.
Если вынести эти поля за пределы класса, то все работает.
Взгляните, приведу целиком unit пустого прокета (на форме одна метка):

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Label1: TLabel;
   procedure FormShow(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 TSQL_Keeper = procedure of object;

TQParam = class(TObject)
public
  SQL_Keeper:array[1..2] of TSQL_Keeper;
  TextFied:WideString;
  constructor Create;
published
  procedure SQL_a1;
end;

var
 Form1: TForm1;
 QParam:TQParam;

implementation

{$R *.dfm}

constructor TQParam.Create;
var  SQLName:shortstring;
begin
  SQLName:="SQL_a1";
  TMethod(SQL_Keeper[1]).Code:=TQParam.MethodAddress(SQLName);
  TMethod(SQL_Keeper[1]).Data:=TQParam;
end;

procedure TQParam.SQL_a1;
begin
 TextFied:="It"s working !"; //ОШИБКА !!!
 Form1.Label1.Caption:=TextFied;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
 QParam:=TQParam.Create;
 QParam.SQL_Keeper[1];
end;

end.


А теперь вопрос. Как можно решить указанную проблему, не вынося поле (TextFied:WideString;) за пределы класса ?


 
Джо ©   (2006-12-13 02:30) [9]

Разумеется. Ибо в TMethod.Data нужно записывать указатель на Self, т.е., на конкретный экземпляр класса, а не всякую ерунду, какую пожелается:

>  TMethod(SQL_Keeper[1]).Data:=TQParam;

А у тебя и экземпляр-то даже не создан на момент присваивания .Data.


 
Джо ©   (2006-12-13 02:32) [10]

А почему работало без  TextFied:="It"s working !"? Потому, что внутри метода обращения к полям объекта не было. А как только оно появилось, понадобился указатель на конкретный экземпляр, то есть, Self. А его-то и нету, точнее, он не корректный (ссылается на сам класс, а не на существующий объект).


 
Джо ©   (2006-12-13 02:34) [11]

Ладно, время позднее, а меня доброта распирает... Да и конфа "Начинающим". Домашнее задание отменяется, привожу решение, оно очевидно, впрочем:

constructor TQParam.Create;
var  SQLName:shortstring;
begin
 SQLName:="SQL_a1";
 TMethod(SQL_Keeper[1]).Code:=TQParam.MethodAddress(SQLName);
 TMethod(SQL_Keeper[1]).Data:= Self;
end;


 
Kostafey ©   (2006-12-13 10:14) [12]

> [11] Джо ©   (13.12.06 02:34)
> Ладно, время позднее, а меня доброта распирает...


Большое спасибо. Все работает.



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

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

Наверх




Память: 0.48 MB
Время: 0.155 c
1-1163407952
Corona
2006-11-13 11:52
2006.12.31
ошибка при работе с ListView


15-1165946715
GanibalLector
2006-12-12 21:05
2006.12.31
Контр.сумма по модулю 2


15-1165610085
tesseract
2006-12-08 23:34
2006.12.31
pocket PC


15-1165815285
Knight
2006-12-11 08:34
2006.12.31
Раз уж появилась ветка про Java...


15-1165520112
GanibalLector
2006-12-07 22:35
2006.12.31
Подмена сер.номера винта





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