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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Неверная передача указателя, Delphi XE2, x64 
:(
    Опции темы
Illusion Dolphin
  Дата 15.7.2012, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

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



Есть код (Delphi XE2 update 4, компиляция x64):

Код

type
  TEnumClassesCallback = function(UserData: Pointer; ClassType: TClass): Boolean; 

function DECEnumClasses(Callback: TEnumClassesCallback; UserData: Pointer): TObject;
begin
  Callback(UserData, nil);
end;

{
//а если тут раскоментировать вместо вложенной функции, то всё окей!
procedure DoEnumClasses(Data: Pointer; ClassType: TObject);
begin
  ShowMessage(IntToHex(NativeInt(Data), 16));
end;
}

procedure TForm10.FormCreate(Sender: TObject);

procedure DoEnumClasses(Data: Pointer; ClassType: TObject);
begin
  ShowMessage(IntToHex(NativeInt(Data), 16)); //возвращает 0000000000000000 !
end;

begin
   DECEnumClasses(@DoEnumClasses, Self);
end;


Ожидалось, что он покажет адрес класса TForm10, но в итоге - нули! Объясните, пожалуйста, почему так. Тот же код, но не как вложенная функция, а как отдельная функция работает как и ожидалось. В 32 бита такого не наблюдается.

Заранее спасибо!

Это сообщение отредактировал(а) Illusion Dolphin - 15.7.2012, 22:13


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Чучмек
Дата 16.7.2012, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


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

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



Дело в том, что вложенная функция (в x64) имеет скрытый параметр, через который передается значение регистра rbp. Зачем? Незнаю еще...
Соответственно нужно добавить дополнительный параметр в тип-функцию.
Код

TEnumClassesCallback = function(rbp:NativeInt;UserData: Pointer; ClassType: TClass): Boolean; 
 


Цитата(Illusion Dolphin @  15.7.2012,  22:06 Найти цитируемый пост)
 TEnumClassesCallback = function(UserData: Pointer; ClassType: TClass): Boolean; 

Цитата(Illusion Dolphin @  15.7.2012,  22:06 Найти цитируемый пост)
procedure DoEnumClasses(Data: Pointer; ClassType: TObject);

Вроде как функция, а вроде как процедура  smile 



--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
Illusion Dolphin
Дата 16.7.2012, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

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



Цитата

Вроде как функция, а вроде как процедура

Пока вырезал из проекта - упрощал и приводил к минимуму - напутал smile, а вообще не работает и с функцией и с процедурой.
Цитата

TEnumClassesCallback = function(rbp:NativeInt;UserData: Pointer; ClassType: TClass): Boolean; 

Да, так оно и происходит, просто не понятно, что с этим делать. Выглядит как какой-то баг внутри делфи, я пока выношу в таком случае внутреннюю функцию наружу - вот боюсь как бы ещё где не вылезло :(


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
bems
Дата 17.7.2012, 10:51 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Illusion Dolphin @  16.7.2012,  22:02 Найти цитируемый пост)
Выглядит как какой-то баг внутри делфи

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


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Illusion Dolphin
Дата 17.7.2012, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

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



Цитата

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

Спасибо, теперь всё понятно! Это старый "хак" который явно многие использовали и этот хак сломался в x64. А то я портирую кусок чужого кода - хотелось сохранить структуру, видимо не получится smile


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
bems
Дата 17.7.2012, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Говоришь поломался только на х64? Хм... Вроде на заре своего знакомства с винапи, еще на дельфи 5, я убедился что нельзя передавать вложенную функцию в качестве коллбека винапишным функциям. Кажется на EnumWindows уже тогда проявлялся этот момент. Хотя может дело в конвенции вызова или моей дырявой памяти


--------------------
Обижено школьников: 8
PM MAIL   Вверх
bems
Дата 18.7.2012, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(bems @  17.7.2012,  22:09 Найти цитируемый пост)
может дело в конвенции вызова
на х64 тоже другая конвенция, так что работало наверное только на дефолтной конвенции



--------------------
Обижено школьников: 8
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.0507 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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