我尝试使用CreateTimerQueueTimer()
来控制C中串行端口的轮询。我对Windows API几乎没有经验,因此我开始使用here中的基本示例。由于某些原因,即使包含WAITORTIMERCALLBACK
和windows.h
并且识别了所有API调用(winbase.h
等),也无法识别(未声明)CreateTimerQueue()
。
相关代码如下
头:
//serial.h
....
#ifdef _WIN32
#include <windows.h>
#include <winbase.h>
#endif
....
和源文件:
//serial.c
VOID CALLBACK port_polling_win(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
//stuff will happen here
}
int create_polling_thread(serial_port *comport)
{
#ifdef _WIN32
HANDLE gDoneEvent;
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 TIMER_RESOLUTION_MS miliseconds
if (!CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK) port_polling_win, &arg, TIMER_RESOLUTION_MS, 0, 0))
{
printf("CreateTimerQueueTimer failed (%d)\n", GetLastError());
return 3;
}
#else
....
#endif
return 0;
}
我尝试将port_polling_win()
声明为VOID WAITORTIMERCALLBACK
,WAITORTIMERCALLBACK
和void WAITORTIMERCALLBACK
,因此CreateTimerQueueTimer()
中的演员阵容不是必要的,但无济于事。 WAITORTIMERCALLBACK
在任何地方都无法识别。
仅供参考,我在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;
}
EDIT2:
我发现WAITORTIMERCALLBACK
winbase.h
中的_WIN32_WINNT >= 0X0500
是#define _WIN32_WINNT 0x0500
的{{1}}。在所有#include
之后添加char hex[] = "0123456789abcdef";
void printHex(unsigned char byte) {
printf("%c%c", hex[byte>>4], hex[byte&0xf]);
}
到我的孤立示例的序言中并没有改变一件事。