Адрес переменной по имени
Модератор: Модераторы
Адрес переменной по имени
Всем привет!
Битый час ковыряюсь, не могу найти, как определить адрес переменной модуля. Как вариант, сошло бы и определение адреса поля класса TObject.FieldAddress, но оно не работает! MethodAddress, при всё при этом, прекрасно отрабатывает.
Где собака порылась?
Битый час ковыряюсь, не могу найти, как определить адрес переменной модуля. Как вариант, сошло бы и определение адреса поля класса TObject.FieldAddress, но оно не работает! MethodAddress, при всё при этом, прекрасно отрабатывает.
Где собака порылась?
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
И, кстати, "вы будете смеяться", но пример из дистрибутива FPC тоже не работает! Вот полный код (правда, я его немного поредактировал, т.к. не нашёл модуля rttiobj, в котором должен быть объявлен TMyTestObject):
p.s. FPC 2.0.4
Код: Выделить всё
program demo;
{ This program demonstrates the GetStrProp function }
{.$mode objfpc}
{$mode delphi}
{$TYPEINFO+}
uses typinfo;
type
TMyTestObject = class
private
s : string;
public
property AnsiStringField : string read s write s;
end;
Var
O : TMyTestObject;
PI : PPropInfo;
begin
O:=TMyTestObject.Create;
O.AnsiStringField := 'hello';
PI:=GetPropInfo(O,'AnsiStringField');
Writeln('String property : ');
Writeln('Value : ',O.AnsiStringField);
// при попытке вызвать GetStrProp выскакивает исключение с названием "Unknown Property"!
Writeln('Get (name) : ',GetStrProp(O,'AnsiStringField'));
Writeln('Get (propinfo) : ',GetStrProp(O,PI));
SetStrProp(O,'AnsiStringField','First');
Writeln('Set (name,''First'') : ',O.AnsiStringField);
SetStrProp(O,PI,'Second');
Writeln('Set (propinfo,''Second'') : ',O.AnsiStringField);
O.Free;
end.p.s. FPC 2.0.4
Блин, вот что значит, вслух произнести проблему.
Если property объявлена как published, то всё работает.
Так что вопрос снимается!
Хы, а FieldAddress так и не возвращает адрес.
Хоть поле ему подставляй, хоть пропертю. Ну ладно, хоть GetStrProp работает, и на том спасибо
Если property объявлена как published, то всё работает.
Так что вопрос снимается!
Хы, а FieldAddress так и не возвращает адрес.
Код: Выделить всё
O.FieldAddress('AnsiStringField');Хоть поле ему подставляй, хоть пропертю. Ну ладно, хоть GetStrProp работает, и на том спасибо
Ага, вот я и нашёл неувязочку!
В доке, и впрямь написано - для published полей генерируется типовая информация для рантайма. Но! Согласно тому же мануалу, эти поля должны иметь тип класса. И действительно, при попытке объявить любую переменную в разделе published, компилер ругается.
Хотя в описании метода TObject.FieldAddress и не сказано, что это самое field может быть любого типа.
Вот такая заковыка.
В доке, и впрямь написано - для published полей генерируется типовая информация для рантайма. Но! Согласно тому же мануалу, эти поля должны иметь тип класса. И действительно, при попытке объявить любую переменную в разделе published, компилер ругается.
Хотя в описании метода TObject.FieldAddress и не сказано, что это самое field может быть любого типа.
Вот такая заковыка.
Stargazer писал(а):Вот ещё над чем я призадумался.
С запуском метода, определенного по имени с помощью MethodAddress, я разобрался. Но теперь и этого мало
Хочется передавать параметры в этот метод
Это уж совсем шаманство, да?
Сам себе отвечаю:
http://forum.vingrad.ru/index.php?act=m ... num=000278
В принципе, ничего сложного, надо только один раз увидеть, как это делается.
На всякий случай, процитирую:
Код: Выделить всё
... }
type
PYourMethod = ^TYourMethod;
TYourMethod = procedure(S: string) of Object;
procedure TMainForm.Button1Click(Sender: TObject);
begin
ExecMethodByName('SomeMethod');
end;
procedure TMainForm.ExecMethodByName(AName: string);
var
PAddr: PYourMethod;
M: TMethod;
begin
PAddr := MethodAddress(AName);
if PAddr <> nil then
begin
M.Code := PAddr;
M.Data := Self;
TYourMethod(M)('hello');
end;
end;
procedure TMainForm.SomeMethod(S: string);
begin
ShowMessage(S);
end; 