Модераторы: Snowy, MetalFan, bems, Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получить адрес функции у класса 
V
    Опции темы
Ak47black
  Дата 1.12.2007, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Здравствуйте.
Меня интересует как правильно получить адрес функции у класса.
(Я хочу потом использовать функцию у класса как CallBack_function, поэтому для этого мне нужно получить адрес)
Например вот такой код
Код

unit Unit2;

interface

type
  TTest = class
  public
    constructor Create;
    function Sample: Integer;
  end;

implementation

function TTest.Sample: Integer;
begin

end;

constructor TTest.Create;
var
  i: Cardinal;
begin
  i:= @Sample; // Тут ошибка Variable required
end;

end.


Подскажите пожалуйста как тут правильно сделать?  smile 
PM MAIL   Вверх
Alexeis
Дата 1.12.2007, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



  Можно присвоить метод переменной типа метод, а потом извлечь адрес функции.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Ak47black
Дата 1.12.2007, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Alexeis, ага так вышло.
Ну всетаки почему напрямую нельзя получить, то до меня недоходит  smile .

Добавлено @ 16:53
Alexeis, а такой код который ниже реально сделать вообще?
Код

  CallBackProc:= waveOutProc;
  WaveOutOpen(@hwo, WAVE_MAPPER, @wfx, Cardinal(@CallBackProc), 0, callback_function);

waveOutProc - функция принадлежащая классу.
При выполнении получаю ошибку
Цитата

Project Test.exe raised exception class EAccessViolation with message 'Access violation at address 0014DB60. Write of address FFFFFC43'.

Пытаюсь процедуру обработки привязать к классу  smile .

Это сообщение отредактировал(а) Ak47black - 1.12.2007, 16:54
PM MAIL   Вверх
MetalFan
Дата 1.12.2007, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



низя метод назначить в кач.колбэка апи функции


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Alexeis
Дата 1.12.2007, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(MetalFan @  1.12.2007,  21:26 Найти цитируемый пост)
низя метод назначить в кач.колбэка апи функции 

  Почему? Метод фактически не отличается от функции. Есть свои особенности, метод реализуется как функция.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
OdesitVadim
Дата 1.12.2007, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 9.11.2007
Где: Одесса:)

Репутация: нет
Всего: нет



Вся загвоздка в том, что в методах есть неявный параметр, токорый указывает на объект. Вам то это не видно, а линковщик, когда собирает, обнаруживает несоответсвие параметров.
PM MAIL   Вверх
Ak47black
Дата 1.12.2007, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Хмм поэтому.
Вообщем у меня у цель, то сделать класс, при использовании которого, каждый экземпляр которого имел-бы свою CallBack функцию и проигровали звук независимо друг от друга.
Как-бы тут сделать может какие идеи есть?

Это сообщение отредактировал(а) Ak47black - 1.12.2007, 23:30
PM MAIL   Вверх
Alexeis
Дата 2.12.2007, 00:31 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Ak47black, так что тот 
Цитата(OdesitVadim @  1.12.2007,  23:15 Найти цитируемый пост)
Вам то это не видно, а линковщик, когда собирает, обнаруживает несоответсвие параметров. 

  Ну эту проблему как раз обойти не сложно, если постараться, то функции можно впарить чего угодно. Можно попробовать такой способ

Код

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure WaveOutProc(hwo : HWAVEOUT; uMsg : UINT; dwInstance : PDWORD;
                          dwParam1 : PDWORD); stdcall;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WaveOutProc(hwo : HWAVEOUT; uMsg : UINT; dwInstance : PDWORD;
                             dwParam1 : PDWORD);
var
  dwParam2 : PDWORD;
Begin
  dwParam2 := dwParam1; dwParam1 := dwInstance; dwInstance := Pointer(uMsg);
  uMsg := hwo; hwo := Integer(self); Self := TForm1(dwInstance);

end;

procedure TForm1.FormCreate(Sender: TObject);
var
  tmp : Pointer;
begin
  waveOutOpen(tmp, 0, tmp, Cardinal(@TForm1.WaveOutProc), Cardinal(self), 0);
end;


Суть его в том что винда думает будто у функции 5 параметров, каждый из которых DWORD у нас так е есть 5м параметром будет Self. Винда конечно же не знает что мы там ждем указатель на объект и пихает туда первый параметр, потому сразу после вызова нужно либо расставить параметры по своим местам, либо переименовать так чтобы не запутаться. Теперь обязательный момент. waveOutOpen разрешает калбэк передать дополнительный параметр, в нем передаем указатель на реальный объект, после вызова в Self мы должны записать это значение см Self := TForm1(dwInstance); Теперь по идее все на своих местах. Просили 5 параметров типа DWORD мы их вам дали по модели stdcall.

  Сомнение у меня вызывает только, то что по модели stdcall параметры передаются справа-налево, если это касается и указателя на класс, то проблем не должно возникнуть.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Ak47black
Дата 2.12.2007, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Alexeis, с этим то кодом Erorr у меня выходит
Цитата

---------------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 0042D2B0 in module 'Project1.exe'. Read of address FFFFFFEC'. Process stopped. Use Step or Run to continue.
---------------------------

С такими параметрами и недолжно работать по идее. 
Цитата

что в методах есть неявный параметр



Это сообщение отредактировал(а) Ak47black - 2.12.2007, 13:35
PM MAIL   Вверх
Alexeis
Дата 2.12.2007, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(Ak47black @  2.12.2007,  11:35 Найти цитируемый пост)
С такими параметрами и недолжно работать по идее. 

  Ну я понадеялся, что хватит сообразительности вместо пустых параметров поставить реальные  smile 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Ak47black
Дата 2.12.2007, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Alexeis, а мне кажется что error изза того что стёк портится.

Добавлено через 2 минуты и 41 секунду
При вызове waveOutProc все параметры сдвинуты на 1 влево.

Добавлено через 3 минуты и 47 секунд
И эррор появляется только после первого выполнения waveOutProc.

Это сообщение отредактировал(а) Ak47black - 2.12.2007, 14:58
PM MAIL   Вверх
Ak47black
Дата 2.12.2007, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Хотя вроде нет
Вот так вызов происходит в Winmm.dll
Код

76B454E6   FF75 20          PUSH DWORD PTR SS:[EBP+20]
76B454E9   53               PUSH EBX
76B454EA   FF75 18          PUSH DWORD PTR SS:[EBP+18]
76B454ED   FF75 14          PUSH DWORD PTR SS:[EBP+14]
76B454F0   56               PUSH ESI
76B454F1   FFD7             CALL EDI

А вот сама пустая процедура CallBack 
Код

0044D938  /. 55             PUSH EBP
0044D939  |. 8BEC           MOV EBP,ESP
0044D93B  |. 83C4 F0        ADD ESP,-10
0044D93E  |. 894D F4        MOV DWORD PTR SS:[EBP-C],ECX
0044D941  |. 8955 F8        MOV DWORD PTR SS:[EBP-8],EDX
0044D944  |. 8945 FC        MOV DWORD PTR SS:[EBP-4],EAX
0044D947  |. 8BE5           MOV ESP,EBP
0044D949  |. 5D             POP EBP
0044D94A  \. C2 0C00        RETN 0C

Чтото я запутался тут  smile 
Какиенибудь идеи есть?
И еше при вызове  WaveOutOpen, парметры ненужно смешать, я пробовал waveOutProc как внизу 
Код

WaveOutOpen(@hwo, WAVE_MAPPER, @wfx, Cardinal(@PWaveOutProc), 0, CALLBACK_FUNCTION);

waveOutProc вызывается один раз, после прохождения получаю error :|
PM MAIL   Вверх
Alexeis
Дата 2.12.2007, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Епрст ну что за 0! я же говорил там должен быть указатель на класс!


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Ak47black
Дата 2.12.2007, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Эммм это в моем случае 0? Где?  smile 
PM MAIL   Вверх
Ak47black
Дата 2.12.2007, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Пытаюсь понять что именно вызывает ошибку чтобы както предотвратить.
Покопав понял, что изза того что стек портиться прога прыгает(возвращается) на 00000000 адрес
Код

76B454E6   FF75 20     PUSH DWORD PTR SS:[EBP+20] // Запоняем стёк параметрами
76B454E9   53             PUSH EBX
76B454EA   FF75 18     PUSH DWORD PTR SS:[EBP+18]
76B454ED   FF75 14     PUSH DWORD PTR SS:[EBP+14]
76B454F0   56              PUSH ESI
76B454F1   FFD7          CALL EDI // тут вызывается CallBack функция в коде программы 0044D938
76B454F3   33C0             XOR EAX,EAX
76B454F5   40               INC EAX
76B454F6   5F               POP EDI
76B454F7   5E               POP ESI
76B454F8   5B               POP EBX
76B454F9   5D               POP EBP
76B454FA   C2 1C00          RETN 1C // Тут изза того что стёк испортился прыгает(возвращается) на EIP 00000000

Я предполагаю что вот этот лишний параметр както его и портит, только как?
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0585 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.