setwaitedtimer函数不会在c中调用回调函数

时间:2014-11-18 12:51:35

标签: c winapi timer

你好我正在尝试Windows中的c程序中的计时器功能。 我的代码如下

#define  _WIN32_WINNT 0x0400
#define WT_EXECUTEINTIMERTHREAD 0x00000020
#include<stdio.h
#include<windows.h>

typedef void (*callbackfunction)();

void timerfunction(callbackfunction cb);

void callback()
{
SYSTEMTIME time;

int millis;

int seconds;
GetSystemTime(&time);
millis =time.wMilliseconds;
seconds=time.wSecond;
printf("\n\ninside callback second=%d, milli=%d\n\n",seconds,millis);
}

void timerfunction(callbackfunction cb)
{
 HWND hwndTimer=NULL;
 HANDLE hnd;
 PHANDLE h_buffer=(PHANDLE)malloc(sizeof(PHANDLE));

 int a;
 int qwDueTime;

  UINT_PTR nIDEvent=1;
  MSG msg;          // message structure 

  LARGE_INTEGER liDueTime;
 liDueTime.QuadPart=-100000000;
 a=10;
  nIDEvent=nIDEvent+1;
  hnd = CreateWaitableTimer(
     0,
    FALSE, 
    0);
  qwDueTime = -5*1000;
  liDueTime.LowPart  = (DWORD) ( qwDueTime & 0xFFFFFFFF );
  liDueTime.HighPart = (LONG)  ( qwDueTime >> 32 );

  SetWaitableTimer(hnd,&liDueTime,20,(PTIMERAPCROUTINE)cb,(LPVOID)a,TRUE);
  // WaitForSingleObject( hnd,20);

  // Wait for the timer.

  }




void main()
{
callbackfunction cb= callback;
int a;
a=10;
timerfunction(cb);

 Sleep(1000000);

}

定时器功能不调用回调函数 请帮忙。 我在Windows上工作

我使用过SetTimer()api,但时间比我指定的多。我正在为音频做这个,所以我希望时间精度在一毫秒内。它进入定时器功能,但不触发回调功能。我正在使用的方式是正确的还是我需要使用waitforSingleObject Api

2 个答案:

答案 0 :(得分:0)

你为什么先设置

liDueTime.QuadPart=-100000000;

会在调用SetWaitableTimer()然后

后10秒触发时间
qwDueTime = -5*1000;
liDueTime.LowPart  = (DWORD) ( qwDueTime & 0xFFFFFFFF );
liDueTime.HighPart = (LONG)  ( qwDueTime >> 32 );

? 只有5000 100 ns单位的负到期时间表示相对延迟仅 500微秒

查看MSDN示例:

#define _SECOND 10000000
qwDueTime = -5 * _SECOND;

你错过了10000倍。

您应该评估SetWaitableTimer的返回值以覆盖错误条件。 链接的MSDN示例代码提供了所有详细信息。

但是,只有Multimedia Timers才能实现1 ms范围内的较短延迟。

答案 1 :(得分:0)

您正在将您的函数名称转换为PTIMERAPCROUTINE。这可能不是您的代码不起作用的原因,但它仍然是非常错误的。

NOT 将函数名称转换为任何内容。 If you need to cast a function, you're doing something wrong.

PTIMERAPCROUTINE的签名是

VOID CALLBACK functionName(LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue);

您的功能必须拥有此签名,尤其是 CALLBACK,因为这与calling convention有关。

如果/当您切换到多媒体或演奏计时器时也是如此。您需要检查这些回调函数签名以获得正确的签名。