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

Вниз

Преобразование типа pointer в указатель метода.   Найти похожие ветки 

 
Kostafey ©   (2005-10-07 21:04) [0]

Прошу помощи у мастеров:

TFunctions.MethodAddress(FunctName);

- возвращает pointer на метод с именем FunctName, где FunctName:shortstring а как этот pointer преобразовать к указателю на метод следующего вида:

TFunc = function (x:real):real of object;

(кстати метод с именем FunctName имеет ту же структуру)

Если писать просто

TFunc(TFunctions.MethodAddress(FunctName));

- то получиться ошибка приведения типов,

TFunc(TFunctions.MethodAddress(FunctName)^);

- тогда компиляция проходит успешно, но при запуске приложение аварийно завершается с ошибкой доступа к памяти (кто б сомневался)

Так как из pointer сделать function (x:real):real of object ???


 
Eraser ©   (2005-10-07 21:25) [1]


> Kostafey ©   (07.10.05 21:04)

Читать справку.
Особенно:
Returns the address of a published method.

Delphi syntax:

class function MethodAddress(const Name: ShortString): Pointer;

C++ syntax:

static void * __fastcall MethodAddress(TClass cls, const ShortString &Name);

void * __fastcall MethodAddress(const ShortString &Name) { return MethodAddress(ClassType(), Name); }

Description

MethodAddress is used internally by the streaming system. When an event property is read from a stream, MethodAddress converts a method name, specified by Name, to a pointer containing the method address. There should be no need to call MethodAddress directly.

If Name does not specify a published method for the object, MethodAddress returns nil (Delphi) or NULL (C++).

Метод и функция/процедура - две большие разницы!


 
Piter ©   (2005-10-07 21:37) [2]

Хм... интересный вопрос... я ответа не знаю...

Eraser ©   (07.10.05 21:25) [1]

ты вообще о чем?


 
Kostafey ©   (2005-10-07 21:38) [3]

Спасибо, конечно, за ответ.

> Читать справку.

Да вроде все смотрел.

> class function MethodAddress(const Name: ShortString): Pointer;

о нем и речь

> If Name does not specify a published method for the object,
>  MethodAddress returns nil (Delphi) or NULL (C++).

Да, я объявил эти методы в разделе published класса.

А как преобразовать типы-то ?


 
Kostafey ©   (2005-10-07 21:39) [4]


> Метод и функция/процедура - две большие разницы!

Да, я уже отказался от функций, теперь работают только методы классов !


 
Kostafey ©   (2005-10-07 21:40) [5]


> Piter ©   (07.10.05 21:37) [2]
>
> Хм... интересный вопрос... я ответа не знаю...
>
> Eraser ©   (07.10.05 21:25) [1]
>
> ты вообще о чем?


Говорит-то но все правильно, но проблемы-то это не решает :(((


 
Zeqfreed ©   (2005-10-07 21:41) [6]

Kostafey ©   (07.10.05 21:04)
А зачем ты используешь модификатор of object? Без него все прекрасно работает. Ну или если он необходим, то:

var
tmp : TFunc;
begin
tmp := Form1.MethodAddress("Foo");
TFunc(tmp)(0);


 
Piter ©   (2005-10-07 21:43) [7]

Да, при всей свой легкости я не знаю как решить задачку :(

Правда, при этом я и не совсем понимаю смысл от использования MethodAddress, но с точки зрения конвертации типов интересно...

По идее:

Kostafey ©   (07.10.05 21:04)
TFunc(TFunctions.MethodAddress(FunctName));


должно работать... ан не работает...


 
Kostafey ©   (2005-10-07 21:43) [8]


> var
> tmp : TFunc;
> begin
> tmp := Form1.MethodAddress("Foo");
> TFunc(tmp)(0);


А вот tmp := Form1.MethodAddress("Foo")
-выдаст ошибку приведения типов !!!


 
Eraser ©   (2005-10-07 21:43) [9]


> Kostafey ©   (07.10.05 21:39) [4]

Ферштейн!
Тады,

TFunc = function (x:real):real of object;
...
var
 fn: TFunc;
begin
 @fn := MethodAddress("testit");
 fn(..); // можно вызывать метод


 
Kostafey ©   (2005-10-07 21:45) [10]


> Piter ©


> должно работать... ан не работает...

Да, верно.
Может какя функция пробразования типов есть ?


 
Kostafey ©   (2005-10-07 21:46) [11]


> Eraser ©   (07.10.05 21:43) [9]
>
>
> > Kostafey ©   (07.10.05 21:39) [4]
>
> Ферштейн!
> Тады,
>
> TFunc = function (x:real):real of object;
> ...
> var
>  fn: TFunc;
> begin
>  @fn := MethodAddress("testit");
>  fn(..); // можно вызывать метод


А ты сам-то пробовал, такое может работать???
Ладно я сейчас !!!


 
begin...end ©   (2005-10-07 21:46) [12]

> Piter ©   (07.10.05 21:37) [2]
> ты вообще о чем?

Видимо, о том, что, как минимум, метод должен быть published.

> Piter ©   (07.10.05 21:43) [7]
> должно работать...

Почему должно?


 
Eraser ©   (2005-10-07 21:46) [13]


> Eraser ©   (07.10.05 21:43) [9]

Здесь testit - published method текущего класса (формы).


 
Eraser ©   (2005-10-07 21:47) [14]


> Kostafey ©   (07.10.05 21:46) [11]

А почему оно должно не работать?


 
Kostafey ©   (2005-10-07 21:49) [15]


>  Eraser ©


> >  @fn := MethodAddress("testit");

Не, пробовал - invalid typecast !!!


 
Eraser ©   (2005-10-07 21:50) [16]


> Kostafey ©   (07.10.05 21:49) [15]

Пробовал - работает!

Что есть fn у тебя ?
И что есть testit ?


 
Piter ©   (2005-10-07 21:50) [17]

Ой, все, я спать... Блин, это ведь простейшая задача...

Это ведь фактически тоже самое что в DLL GetProcAddress использовать...
Тьфу, я спать блин...

Eraser в [15] все верно написал...


 
Kostafey ©   (2005-10-07 21:52) [18]


> Eraser ©   (07.10.05 21:50) [16]
>
>
> > Kostafey ©   (07.10.05 21:49) [15]
>
> Пробовал - работает!
>
> Что есть fn у тебя ?
> И что есть testit ?


ТЫ ЧТО ИЗДЕВАЕЩЬСЯ ???

var i:byte;
   FunctName:shortstring;
   FFF:TFunc;
begin
 for i:=1 to VariantNumbers do
 begin
   FunctName:="f_var"+inttostr(i);
   @FFF:=TFunc(TFunctions.MethodAddress(FunctName));
 end;
.....

@FFF:=TFunc(TFunctions.MethodAddress(FunctName)); - не работает !


 
Eraser ©   (2005-10-07 21:55) [19]


> Kostafey ©   (07.10.05 21:52) [18]

И где в [9] ты видишт вот эту галиматью @FFF:=TFunc(TFunctions.MethodAddress(FunctName)); ? )


 
Kostafey ©   (2005-10-07 21:56) [20]


>  Eraser ©   (07.10.05 21:50) [16]

Уй, прошу прощения !

@FFF:=TFunctions.MethodAddress(FunctName); - РАБОТАЕТ!

TFunc(...) Забыл убрать - жутко сорри !


 
Eraser ©   (2005-10-07 21:57) [21]


> Kostafey ©   (07.10.05 21:56) [20]

Бывает )


 
Kostafey ©   (2005-10-07 21:58) [22]

...замяли ладно ?

ВОПРОС ПОХОЖЕ РЕШЕН !
СПАСИБО !!!


 
Zeqfreed ©   (2005-10-07 22:00) [23]

[6] работает, проверял.
Вот "полный" код:

...
type
 TFunc = function (x : Real) : Real;

 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 published
  function Foo(x : Real) : Real;
 end;

...

function TForm1.Foo(x : Real) : Real;
begin
ShowMessage("It works");
end;

procedure TForm1.Button1Click(Sender: TObject);
var
tmp : TFunc;
begin
tmp := Form1.MethodAddress("Foo");
TFunc(tmp)(0);
end;


Компилятор D7, хотя врядли это имеет значение в данном случае.


 
Zeqfreed ©   (2005-10-07 22:02) [24]

Zeqfreed ©   (07.10.05 22:00) [23]
Ой, извиняюсь, работает, конечно, но там я убрал of object, хотя вроде потом обратно возвращал.. эх.. ну хорошо, что ты уже нашёл решение :)


 
begin...end ©   (2005-10-07 22:02) [25]

Если фигурирующий тут метод обращается к полям объекта либо вызывает динамические или виртуальные методы, то нужно ещё связать его с объектом, иначе будет ошибка на этапе исполнения.

Более правильно делать так:

type
 TFunc = function(x: Real): Real of object;
var
 fn: TFunc;
begin
 TMethod(fn).Code := MethodAddress("...");
 TMethod(fn).Data := идентификатор_соответствующего_экземпляра_класса;
 fn(...);
end

Содержимое поля Data внутри метода будет рассматриваться как Self.


 
Kostafey ©   (2005-10-07 22:09) [26]


> Zeqfreed ©   (07.10.05 22:02) [24]


> tmp := Form1.MethodAddress("Foo");

Спасибо, вопрос решен, но у меня упорно не работает тогда
Varints[i]:=TFunctions.MethodAddress(FunctName);
А так работает:
@Varints[i]:=TFunctions.MethodAddress(FunctName);


 
Eraser ©   (2005-10-07 22:14) [27]


> Kostafey ©   (07.10.05 22:09) [26]

Лучше делай через TMethod, как begin...end советовал - это более правильно.



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

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

Наверх




Память: 0.51 MB
Время: 0.041 c
1-1128314099
NikNet
2005-10-03 08:34
2005.10.30
Как быстро сравнить два TBITMAP?


6-1121179345
n0p
2005-07-12 18:42
2005.10.30
Indy9: Nagle


5-1106042112
Aleksandr.
2005-01-18 12:55
2005.10.30
Как повесить обработчик на открытие/закрытие DataSet a у компонен


14-1128508788
NewWonder
2005-10-05 14:39
2005.10.30
Проблема с компьютерами..


14-1129112039
Mike Kouzmine
2005-10-12 14:13
2005.10.30
Подробности происхождения современного человека





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