C windows中的计时器队列

C windows中的计时器队列,c,windows,winapi,timer,C,Windows,Winapi,Timer,我试图使用CreateTimerQueueTimer()来控制C中串行端口的轮询。我对windows API没有什么经验,因此我从使用中的一个基本示例开始。由于某些原因,WAITORTIMERCALLBACK无法识别(未声明),即使包含了windows.h和winbase.h,并且所有API调用(CreateTimerQueue()等)都被识别 有关守则如下: 标题: //serial.h .... #ifdef _WIN32 #include <windows.h> #incl

我试图使用
CreateTimerQueueTimer()
来控制C中串行端口的轮询。我对windows API没有什么经验,因此我从使用中的一个基本示例开始。由于某些原因,
WAITORTIMERCALLBACK
无法识别(未声明),即使包含了
windows.h
winbase.h
,并且所有API调用(
CreateTimerQueue()
等)都被识别

有关守则如下:

标题:

//serial.h

....

#ifdef _WIN32
#include <windows.h>
#include <winbase.h>
#endif

....
我尝试将
port\u polling\u win()
声明为
VOID WAITORTIMERCALLBACK
WAITORTIMERCALLBACK
VOID WAITORTIMERCALLBACK
,因此强制转换
CreateTimerQueueTimer()
是不必要的,但没有效果<代码>等待返回在任何地方都无法识别

仅供参考,我正在64位Win7上使用MinGW GCC进行构建

编辑:如果有任何问题,则单独的示例也不起作用:

/*
 * main.c
 */

#include <windows.h>
#include <winbase.h>
#include <stdio.h>

HANDLE gDoneEvent;

VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
    if (lpParam == NULL)
    {
        printf("TimerRoutine lpParam is NULL\n");
    }
    else
    {
        // lpParam points to the argument; in this case it is an int

        printf("Timer routine called. Parameter is %d.\n",
                *(int*)lpParam);
        if(TimerOrWaitFired)
        {
            printf("The wait timed out.\n");
        }
        else
        {
            printf("The wait event was signaled.\n");
        }
    }

    SetEvent(gDoneEvent);
}

int main()
{
    HANDLE hTimer = NULL;
    HANDLE hTimerQueue = NULL;
    int arg = 123;

    // Use an event object to track the TimerRoutine execution
    gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (NULL == gDoneEvent)
    {
        printf("CreateEvent failed (%d)\n", GetLastError());
        return 1;
    }

    // Create the timer queue.
    hTimerQueue = CreateTimerQueue();
    if (NULL == hTimerQueue)
    {
        printf("CreateTimerQueue failed (%d)\n", GetLastError());
        return 2;
    }

    // Set a timer to call the timer routine in 10 seconds.
    if (!CreateTimerQueueTimer( &hTimer, hTimerQueue,
            (WAITORTIMERCALLBACK)TimerRoutine, &arg , 10000, 0, 0))
    {
        printf("CreateTimerQueueTimer failed (%d)\n", GetLastError());
        return 3;
    }

    // TODO: Do other useful work here

    printf("Call timer routine in 10 seconds...\n");

    // Wait for the timer-queue thread to complete using an event
    // object. The thread will signal the event at that time.

    if (WaitForSingleObject(gDoneEvent, INFINITE) != WAIT_OBJECT_0)
        printf("WaitForSingleObject failed (%d)\n", GetLastError());

    CloseHandle(gDoneEvent);

    // Delete all timers in the timer queue.
    if (!DeleteTimerQueue(hTimerQueue))
        printf("DeleteTimerQueue failed (%d)\n", GetLastError());

    return 0;
}
/*
*main.c
*/
#包括
#包括
#包括
处理gDoneEvent;
无效回调TimerRoutine(PVOID lpParam,BOOLEAN TimerOrWaitFired)
{
if(lpParam==NULL)
{
printf(“TimerRoutine lpParam为空\n”);
}
其他的
{
//lpParam指向参数;在本例中,它是一个int
printf(“调用了计时器例程。参数为%d。\n”,
*(int*)lpParam);
如果(TimerOrWaitFired)
{
printf(“等待超时。\n”);
}
其他的
{
printf(“等待事件已发出信号。\n”);
}
}
SetEvent(gDoneEvent);
}
int main()
{
句柄hTimer=NULL;
HANDLE hTimerQueue=NULL;
int arg=123;
//使用事件对象跟踪TimerRoutine执行
gDoneEvent=CreateEvent(NULL、TRUE、FALSE、NULL);
if(NULL==gDoneEvent)
{
printf(“CreateEvent失败(%d)\n”,GetLastError());
返回1;
}
//创建计时器队列。
hTimerQueue=CreateTimerQueue();
if(NULL==hTimerQueue)
{
printf(“CreateTimerQueue失败(%d)\n”,GetLastError());
返回2;
}
//设置计时器以在10秒内调用计时器例程。
如果(!CreateTimerQueueTimer(&hTimer,hTimerQueue,
(WAITORTIMERCALLBACK)时间例程和参数,10000,0,0)
{
printf(“CreateTimerQueueTimer失败(%d)\n”,GetLastError());
返回3;
}
//TODO:在这里做其他有用的工作
printf(“在10秒内调用计时器例程…\n”);
//使用事件等待计时器队列线程完成
//对象。线程将在此时向事件发送信号。
if(WaitForSingleObject(gDoneEvent,无限)!=WAIT\u OBJECT\u 0)
printf(“WaitForSingleObject失败(%d)\n”,GetLastError());
CloseHandle(gDoneEvent);
//删除计时器队列中的所有计时器。
如果(!DeleteTimerQueue(hTimerQueue))
printf(“DeleteTimerQueue失败(%d)\n”,GetLastError());
返回0;
}
编辑2:
我发现
WAITORTIMERCALLBACK
是在
winbase.h
中定义的,如果
\u WINNT>=0X0500
。在我的独立示例的序言中添加一个
\define\u WIN32\u WINNT 0x0500
,在所有的
\include
之后,并没有改变任何事情。

如果你需要一个演员阵容,那你就错了™. 如果删除强制转换时代码没有编译,则函数签名是错误的。如果是的话,一切都很好。不过,在MSDNI链接的示例中出现了cast。不管怎么说,这是无关紧要的。问题是,即使windows.h和winbase.h已成功包括在内,也无法识别WaitorMercallback。^^^正如@IInspectable所说。这是一个函数指针,所以请删除强制转换,看看会发生什么。另外,可能需要stdcall而不是cdecl?不确定。在包含之后添加它不起作用。在包含
windows.h
之前,您需要定义
\u WIN32\u WINNT
。实际上,它确实改变了一切!定义
\u WIN32\u WINNT
并删除强制转换解决了问题!是时候停止工作回家了!谢谢大家!
/*
 * main.c
 */

#include <windows.h>
#include <winbase.h>
#include <stdio.h>

HANDLE gDoneEvent;

VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
    if (lpParam == NULL)
    {
        printf("TimerRoutine lpParam is NULL\n");
    }
    else
    {
        // lpParam points to the argument; in this case it is an int

        printf("Timer routine called. Parameter is %d.\n",
                *(int*)lpParam);
        if(TimerOrWaitFired)
        {
            printf("The wait timed out.\n");
        }
        else
        {
            printf("The wait event was signaled.\n");
        }
    }

    SetEvent(gDoneEvent);
}

int main()
{
    HANDLE hTimer = NULL;
    HANDLE hTimerQueue = NULL;
    int arg = 123;

    // Use an event object to track the TimerRoutine execution
    gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (NULL == gDoneEvent)
    {
        printf("CreateEvent failed (%d)\n", GetLastError());
        return 1;
    }

    // Create the timer queue.
    hTimerQueue = CreateTimerQueue();
    if (NULL == hTimerQueue)
    {
        printf("CreateTimerQueue failed (%d)\n", GetLastError());
        return 2;
    }

    // Set a timer to call the timer routine in 10 seconds.
    if (!CreateTimerQueueTimer( &hTimer, hTimerQueue,
            (WAITORTIMERCALLBACK)TimerRoutine, &arg , 10000, 0, 0))
    {
        printf("CreateTimerQueueTimer failed (%d)\n", GetLastError());
        return 3;
    }

    // TODO: Do other useful work here

    printf("Call timer routine in 10 seconds...\n");

    // Wait for the timer-queue thread to complete using an event
    // object. The thread will signal the event at that time.

    if (WaitForSingleObject(gDoneEvent, INFINITE) != WAIT_OBJECT_0)
        printf("WaitForSingleObject failed (%d)\n", GetLastError());

    CloseHandle(gDoneEvent);

    // Delete all timers in the timer queue.
    if (!DeleteTimerQueue(hTimerQueue))
        printf("DeleteTimerQueue failed (%d)\n", GetLastError());

    return 0;
}