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

Вниз

Преобразование типа 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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.062 c
1-1128521993
Aleksey
2005-10-05 18:19
2005.10.30
Image.Canvas и LineTo


4-1125003411
Nazi
2005-08-26 00:56
2005.10.30
условное объявление функции


14-1128674620
SpecLab
2005-10-07 12:43
2005.10.30
Стратегия игры в Lines


14-1128762825
pazitron_brain
2005-10-08 13:13
2005.10.30
Какой язык выбрать для создания сайтов.?


10-1106223619
uncle
2005-01-20 15:20
2005.10.30
body for IHTMLDocument2