Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.31;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.054 c
2-1165914151
Kvinta
2006-12-12 12:02
2006.12.31
Поиск в дате в Гриде


2-1165763056
__Алексей
2006-12-10 18:04
2006.12.31
Корректная работа с записями, содержащими string.


15-1166046445
sat
2006-12-14 00:47
2006.12.31
задача нужны идеи


2-1165681703
atas-sheriff
2006-12-09 19:28
2006.12.31
ClientSocket


2-1165666026
xela
2006-12-09 15:07
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
Английский Французский Немецкий Итальянский Португальский Русский Испанский