|
Location: Desktop development - C/C++ License: The Intelliproject Open License (IPOL) Using class members as callback functionsPosted by Silviu CarageaIn the object oriented programming of C++, using C-style callback functions is not possible without some little hacks. This article describes how can we use class members as callback functions. |
Skill: AdvancedPosted: 22/12/2008Views: 755Rating: 5.00 /5Popularity: 0.00 |
| Sign Up to vote for this article |
In computer science, a callback is executable code that is passed as an argument to other code. It allows a lower-level software layer to call a function defined in a higher-level layer.
Usually, the higher-level code starts by calling a function within the lower-level code passing to it a pointer or handle to another function. While the lower-level function executes, it may call the passed-in function any number of times to perform some subtask.
Some functions examples which use callbacks are:
EnumWindows - Enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.qsort() - implements a quick-sort algorithm to sort an arrayCreateThread() - Creates a thread to execute within the virtual address space of the calling process.In the object oriented programming of C++, using C-style callback functions is not possible without some little hacks. The problem is that we can pass only static member functions in these places. But class functions have no implicit this pointer, so they are rather limited. What we want is to use a real member function as a callback.
The article describes how this can be achieved by using Thunk Objects.
Member functions of classes use a different calling convention named thiscall. This convention operates much like __stdcall except that the "this" pointer (which is effectively a hidden argument) is stored in the ECX register.
When you call a member function the machine code will looks like these:
mov ECX, pThis jmp offsetProcedure
The first instruction stores the pointer to the object in question in ECX register. The second will be the relative jump needed to arrive at the start of the function.
When we declare our thunk object we need to set the packing to 1 so we make sure that there are no alignment gaps.
The values for m_mov and m_jmp are constant. m_this is store the object pointer as it's value. m_relproc is a bit more complicated. The jmp instruction needs a relative value, so we need to calculate the distance from where the instruction pointer is now to where it needs to be, in bytes. This distance is saved in m_relproc.
Finally we call FlushInstructionCache. This flushes the instruction cache for the current process to ensure that no processor has a stale copy of the instructions we have just created on the heap.
First of all we must extend our CThread class from CThunk :
In our class constructor we must initialize our thunk.
Where ThreadProc is our member function that we want to use as callback function.
Our Start() function which will create the new thread is declared as follows:
If you want to see the complete implementation of CThread class you can download the attachment.
The application contained in the article attachment use CThread to display some numbers in a new thread for 3 seconds.
Do not try to run this piece of code on other architecture than x86 because it will not works.
This article, along with any associated source code and files, is licensed under The Intelliproject Open License (IPOL)
| Silviu Caragea
| Silviu Caragea is the Founder, Administrator and Chief Editor who wrote and runs The IntelliProject. He's been programming since 2000 and now he's student at The Faculty of Economic Cybernetics, Statistics and Informatics from Bucharest. In the same time he's working as software developer at Cratima Software, a Romanian software and web design company that activates both on the local and foreign market, providing its customers with software development services, internet and intranet solutions, web design, graphic design and IT consultancy. His programming experience includes: - C,C++, Visual C++(Win32 API, MFC, ADO, STL, DAO, ODBC, ATL, COM, DirectShow, DirectDraw, WTL) - Open Source libraries :CURL & Boost - HTML, CSS - Java (SE,ME) - JavaScript, Ajax, Google Web Toolkit (GWT) - Php, MySQL -Oracle, PL SQL - C# .NET -Objective C, IPhone SDK, Cocoa Location: |
Sign up to post message on the article message board!