Low resolution timer class for Visual C++ and GNU C++ under MingW






3.94/5 (9 votes)
Mar 25, 2005
2 min read

75546

1978
LRTimer - universal low resolution timer class with its own thread.
Introduction
I was writing a small project for a friend of mine that needed a simple low-resolution timer to be used to call a function in equal time intervals as you usually do. When I Googled for timer classes, I found some code in C with __stdcall
static linking, and since I prefer all my code to be encapsulated I decided to write my own timer class that will take any callback function instead.
The LRTimer
class can be used in GNU C++/MingW and Visual C++ 6.0 projects without any changes to the source code. The example project in demo package has been compiled with Bloodshed Dev-C++ 4.9.9.1.
The challenge
The biggest problem I came about was how to use the class member function as a callback parameter for CreateThread
and SetWaitableTimer
API calls. Both the calls require that you provide a static callback C-type function reference.
I have found a good solution by Daniel Lohmann in his article "Use member functions for C-style callbacks and threads - a general solution" at the CodeProject and swiftly adopted it to my timer project.
Daniel uses an adapter static
method as a wrapper to call non-static member functions. The idea behind adapter is to convert the _cdecl
or _stdcall
calls (C convention) into thiscall
- a default call convention for class members. The conversion is necessary since thiscall
passes additional parameters to your member function when calling it, namely this
, and a callback function usually requires specified number of arguments. Compiler first adds an additional parameter to arglist
and then tries to match the number or arguments for that call - great! It is also worth noting that if you want to be able to use non-static class variables within a callback method you cannot use static callback functions by default.
timerThread
is the non-static callback function that will be wrapped and passed to the CreateThread
API call to create new threads when timer.start()
is called.
// timer clocking thread runtine virtual DWORD WINAPI timerThread();
// wrapper to thread runtine so it can be used within a class static DWORD WINAPI timerThreadAdapter(PVOID _this) { return ((LRTimer*) _this)->timerThread(); }
Note that timerThread
takes no parameters and timerTreadAdapter
takes one (void *)
- placeholder for this
. this
is then cast to the class pointer (LRTimer *)
and is used to call non-static timerThread
- neat solution! If you now look at how timerThreadAdapter
is called you will notice that this
is passed explicitly as its argument:
m_hTimerThread = CreateThread(NULL, 0, timerThreadAdapter, this ,0,&m_iID);
Download the source code to see how all this is done. That is all I wanted to share with you today.
Please feel free to use the LRTimer
class in your own projects and I would appreciate if you drop me a line about how you've used it.
Happy coding!