65.9K
CodeProject is changing. Read more.
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.94/5 (9 votes)

Mar 25, 2005

2 min read

viewsIcon

75546

downloadIcon

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!