Форум: "Основная";
Текущий архив: 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.039 c