Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2007.08.05;
Скачать: [xml.tar.bz2];

Вниз

Вызов функции по таймеру   Найти похожие ветки 

 
lexicss ©   (2007-05-29 11:01) [0]

Привет, народ! Вот тут упёрся в одну проблемку, может вы поможете разобрать и решить.
Работаю на Delphi 5 и вот наткнулся на такую ситуацию. Есть у меня одна функция и мне её надо вызвать спустя какой-то интервал времени, делаю это с помощью SetTimer. В чём странность? Так вот: в 98-ой винде работает всё нормально. В XP функция таймера срабатывает дважды, а в 2000-ой мало того что срабатывает функция дважды, так после второго завершения программа вылетает с исключением "Access violation", притом не важно что выполняется в функции(процедуре) вызываемой по таймеру.
Приведу приметивнейший пример


unit Main;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
var
 Form1: TForm1;
procedure MyFunc(hWnd: THandle; uMsg: DWord; idEvent: DWord; dwTime: DWord);
implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
 SetTimer(0,0,5000,@MyFunc);
end;
procedure MyFunc(hWnd: THandle; uMsg: DWord; idEvent: DWord; dwTime: DWord);
begin
 if dwTime = 0
 then beep;
end;
end.

Проведя некоторые исследования, я заметил такую особенность, если число параметров в вызываемой функции не превышает 3, то такой ситуации не возникает(из ассемблерного кода видно, что если в функции большех трёх параметров, то 4-ый и последующие уже передаются не через регистры, а через стэк). Ещё одна особенность, если процедуру MyFunc вызывать с соглашение stdcall, то тоже всё нормально.
Очень важно узнать почему так? Может здесь какая-то несовместимость Delphi 5 и Windows 2000(и выше)?
И как тогда выкручиваться при использовании SetTimer в Delphi 5, так как программа должна быть универсальной и работать как под 98-ой, как под 2000-ой и др одинаково?

Как я понял : Моя процедура MyFunc является callback API-шной и следовательно нуждается в директиве stdcall. Если я понял что-то не так - поправьте, пожалуйста.
Но всё же остаётся открытым вопрос, почему в Windows 98 эта функция работатет нормально без stdcall, хоть в ней и больше 3-х параметров? Может ещё какие будут варианты объяснения кроме случайности? Если кто что толкового подскажет, буду признателен.


 
Сергей М. ©   (2007-05-29 11:09) [1]


> Моя процедура MyFunc является callback API-шной и следовательно
> нуждается в директиве stdcall


Да, нуждается.


> почему в Windows 98 эта функция работатет нормально


Просто тебе повезло.


 
MBo ©   (2007-05-29 11:10) [2]

>Очень важно узнать почему так?
Потому, что таймерная функция должна точно соответствовать прототипу по числу и типам параметров, и соглашение о вызове для этого прототипа именно stdcall. Так что незачем искать приключений...


 
VPBar   (2007-05-29 11:18) [3]

//Очень важно узнать почему так?
Если параметров меньше 3 то функция передает мусор в регистрах но не портит стэк. Если больше 3 то портит стек и из-за этого вылетает ошибка (адрес возврата на стеке ведь тоже хранится, и может быть запорчен).
// Может здесь какая-то несовместимость Delphi 5 и Windows 2000(и выше)?
Никаких несовместимостей.
//И как тогда выкручиваться
Не надо выкручиваться делай правильно - ставь нужное соглашение о вызове (stdcall в данном случае)


 
lexicss ©   (2007-05-30 14:04) [4]

Вот тока всё же странно чего стэк не рушется в 98-ой и работает нормально без stdcall?
Спасибо, народ. Вы мне помогли.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2007.08.05;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.038 c
15-1183886756
ArtemESC
2007-07-08 13:25
2007.08.05
Нет ли у кого МГТС Москвы и Московской области?


15-1182039230
Bell
2007-06-17 04:13
2007.08.05
Как у TPanel открыть события колеса мыши и клавиш?


11-1166710953
Fregl
2006-12-21 17:22
2007.08.05
Сильно глючная работа при проектировании GUI c использованием MCK


2-1183982427
Nightmare
2007-07-09 16:00
2007.08.05
архивирование


8-1162310301
Jimmy
2006-10-31 18:58
2007.08.05
Кривые Безье





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский