Как вызвать метод класса имея его указатель?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Как вызвать метод класса имея его указатель?

Сообщение zub » 02.07.2016 19:31:44

resident
>>А через него можно получить метод без указателя на класс?
слабо понимаю о чем вы. что есть указатель на класс?
Глядим как оно определено:
Код: Выделить всё
       TMethod = record
         Code : CodePointer;
         Data : Pointer;
       end;

имеем указатель на сам метод и указатель на инстанс класса.

>>Именно такой о каком ТС спрашивал в первом посте.
Это не имеет никакого смысла, MysticCoder прав, вы нет.
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как вызвать метод класса имея его указатель?

Сообщение resident » 02.07.2016 20:29:16

zub писал(а):слабо понимаю о чем вы. что есть указатель на класс?

MysticCoder писал(а):У него есть указатель на класс

Это я скопировал у "правильного" MysticCoder. Пардон, конечно я должен был написать "указатель на экземпляр класса".
zub писал(а):имеем указатель на сам метод и указатель на инстанс класса

Как присвоить этот "указатель на сам метод"?
Код: Выделить всё
type
  TFunc = function (arg : integer) : integer;
...
B: TFunc;
...
B := TFunc(TMethod(@SomeClass.SomeMethod).Code);

Всё компилируется. При отладке по шагам заходит в функцию. Result из функции возвращает. Но! Я не могу передать аргумент в функцию. Параметр arg равен какому-то левому значению 35583532.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Как вызвать метод класса имея его указатель?

Сообщение zub » 02.07.2016 20:45:04

Проблема не в как присвоить, а как вызвать. Всё что "of object" имеет скрытый параметр self. Добавте его в сигнатуру TFunc - это какраз "ненужный" "указатель на класс"))
Код: Выделить всё
TFunc = function (self:pointer; arg : integer) : integer;register;//ЕМНИП примерно так, возможно забыл const для self и модификатор возможно не register...


Такчто или по человечески как описано выше, или вашими окольными путями - от "указатель на класс" никуда не дется.
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как вызвать метод класса имея его указатель?

Сообщение resident » 02.07.2016 23:43:14

Ok
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Как вызвать метод класса имея его указатель?

Сообщение AlphaBlend » 03.07.2016 11:28:51

Код: Выделить всё
type

Func =  function (arg:Integer):Integer;
Pfunc = ^Func;



function test(ITem:Integer):Integer;

var
  Form1: TForm1;

implementation

{$R *.lfm}

  function test(item:Integer):integer;
  begin
       result:=item + 100;
  end;

  { TForm1 }

  procedure TForm1.Button1Click(Sender: TObject);
  var
    PAfunc:Pfunc;
  begin
      new(PAfunc);
      PAfunc^:=@test;
         showmessage(IntToStr(PAfunc^(10)));
      dispose(PAfunc);
  end;
                                               


не так ? ))

Добавлено спустя 35 секунд:
аналогично проделывается с методами классов :roll:

Добавлено спустя 17 минут 9 секунд:
Точно так же параметры указателю на метод передаются ))
Код: Выделить всё
type

Func =  function (arg:Integer):Integer;
Pfunc = ^Func;
ClassMethod = function (arg: Integer):integer of object;
PClassMethod = ^ClassMethod;

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

  TAClass = class
     function MethodTest(arg: Integer):integer;
  end;

function test(ITem:Integer):Integer;

var
  Form1: TForm1;

implementation

{$R *.lfm}
  function TAClass.MethodTest(arg:Integer):Integer;
  begin
      result:=arg + 200;
  end;


  function test(item:Integer):integer;
  begin
       result:=item + 100;
  end;

  { TForm1 }

  procedure TForm1.Button1Click(Sender: TObject);
  var
    PAfunc:Pfunc;
    MyClass :TAClass;
    FPClassMethod : PClassMEthod;
  begin
      new(PAfunc);
      PAfunc^:=@test;
      showmessage(IntToStr(PAfunc^(10)));
      dispose(PAfunc);
      MyClass := TAClass.Create;
      new(FPClassMethod);
      FPCLassMEthod^:= @MyClass.MethodTest;
      showmessage(IntToStr(FPClassMethod^(15)));
      dispose(FPClassMethod);
      MyClass.Free;
  end;                                           


Добавлено спустя 3 минуты 42 секунды:
первое окошечко "выбросит " 110 , второе - 215 . Значит все работает правильно - указатель на функцию или метод "берутся " , при вызове параметры им "отдаются " , указатели уничтожаются без "последствий" - никаких "плохих окошечек с красным крестиком" не выбрасывается :wink:

Добавлено спустя 14 минут 4 секунды:
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
  type
    TClassPointer = ^TAClass;
  var
    PAfunc:Pfunc;
    MyClass :TAClass;
    FPClassMethod : PClassMEthod;
    ClassPOinter: TClassPointer;
  begin
     //вариант со вложенным указателем
     //создаем экземпляр
       MyClass:=TAClass.Create;
     // получаем укзаатели

     new(ClassPOinter);   //указатель на  экземпляр
     new (FPCLassMEthod);
        ClassPointer^:=MyClass;
     // используя указатель на  экземпляр получаем указатель на метод ^_^
     FPCLassMethod^:=@ClassPointer^.MethodTest;

     // вывзываем  метод , используя  указатель , полученный  от указателя ^_^

     showmessage(IntToStr(FPClassMethod^(150)));

     dispose(ClassPointer);
     dispose(FPCLassMethod);
     MyClass.Free;

  end;                                             


Добавлено спустя 1 минуту 49 секунд:
Вам так надо было ? ) "Указатель на метод , полученный от указателя на экземпляр класса, вызываемый с передачей ему параметров " ) ? :roll:
Аватара пользователя
AlphaBlend
постоялец
 
Сообщения: 207
Зарегистрирован: 22.05.2016 10:13:10

Re: Как вызвать метод класса имея его указатель?

Сообщение resident » 03.07.2016 14:12:21

AlphaBlend
AlphaBlend писал(а):Вам так надо было ? )

Мне нет. Ваш шаблон:
Код: Выделить всё
ClassMethod = function (arg: Integer):integer of object;

Не соответствует шаблону задания.
Код: Выделить всё
TFunc = function(arg : integer): integer;


Шаблон в задании ведь не взялся из неоткуда. Значит функция по такому шаблону используется где-то дальше. Например, в численных методах, хоть бы и нахождение корня методом деления пополам. Т.е. функция с шаблоном "of object" не прикрутится там дальше, где должна быть по шаблону без него.
Я пробовал открутить функцию от "ссылки на объект" - не получается. См. выше.
Последний раз редактировалось resident 03.07.2016 14:46:14, всего редактировалось 1 раз.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Как вызвать метод класса имея его указатель?

Сообщение AlphaBlend » 03.07.2016 14:33:32

эммм... :shock:

Добавлено спустя 17 часов 16 минут 48 секунд:
гугл уверяет , что так делать нельзя ) Метод - это метод , а функция - это функция :lol: Как чего придумаете над бедным лазарусом поизвдеваться ) Через голову штаны одеваете , ей-Богу :lol: :lol: Создайте экземпляр класса и вызывайте ) оберните его функцией , которая будет только в своих границах создавать экземпляр класса , работать с методом , возвращать результат его работы , и уничтожать :roll:
Аватара пользователя
AlphaBlend
постоялец
 
Сообщения: 207
Зарегистрирован: 22.05.2016 10:13:10

Re: Как вызвать метод класса имея его указатель?

Сообщение Снег Север » 04.07.2016 08:21:21

Вызывать метод класса не имея доступа к описанию класса - абсурдное извращение. Если уж так не хочется создавать экземпляр класса, то ведь есть class function/procedure.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Как вызвать метод класса имея его указатель?

Сообщение vvvch » 04.07.2016 11:15:28

CRobin
Столкнулся с похожей проблемой. Решил так:
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
vvvch
постоялец
 
Сообщения: 105
Зарегистрирован: 26.04.2013 11:05:39
Откуда: г.Боровичи, Новг. обл.

Re: Как вызвать метод класса имея его указатель?

Сообщение resident » 05.07.2016 01:11:08

AlphaBlend писал(а):Создайте экземпляр класса и вызывайте ) оберните его функцией , которая будет только в своих границах создавать экземпляр класса , работать с методом , возвращать результат его работы , и уничтожать :roll:

Да. Только зачем же его каждый раз создавать и уничтожать внутри функции? В модуле сбоку функции создал бы и уничтожил класс всего один раз за всю работу программы.

Снег Север писал(а):Если уж так не хочется создавать экземпляр класса

Об этом здесь даже речи не было.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Как вызвать метод класса имея его указатель?

Сообщение AlphaBlend » 05.07.2016 12:13:43

а не проще его создать "глобально" и через указатель вызывать в любой точке программы ? ( создатьфайлик "kernel.pas" ) , в нем объявить переменную - экземпляр , и используя указатель на эту переменную сделать "Create". В любом модуле программы пишется uses Kernel и функция досутпна как переменная.метод :shock:

Добавлено спустя 49 секунд:
Я эток тому , что если есть необходимость "везде" вызывать эту функцию , используя один единственный экземпляр :roll:
Аватара пользователя
AlphaBlend
постоялец
 
Сообщения: 207
Зарегистрирован: 22.05.2016 10:13:10

Пред.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 225

Рейтинг@Mail.ru