The most elegant way to encapsulate WinAPI callbacks inside a class?

I doubt this is in any way elegant but, IMO, the easiest is to convert the address of a method of a class to a procedure address and pass it to the winapi. Sure, it's a hack, but the VCL does the very same with classes. MakeObjectInstance if only for a specific construct.. See this question for a source for this kind of implementaion and some other, more OO ways to handle the situation.

Up vote 2 down vote favorite 3 share g+ share fb share tw.

I am thinking about elegant way to encapsulate WinAPI callbacks inside a class. Suppose I am making a class handling asynchronous I/O. All Windows callbacks should be stdcall functions, not class methods (I need to pass their addresses to ReadFileEx WinAPI function for example).

So, I cannot just pass method addresses as a callback routines to WinAPI functions. What is the most elegant way to encapsulate functionality of this type inside a class so that the class have events OnReadCompleted and OnWriteCompleted (I am using Delphi as a primary language, but I guess the situation must be the same in C++ because class methods are different from simple methods by the fact, that the first hidden parameter of them is this link. Of course this class is not a singleton and there can be many of them created by app at the same time.

What do you think would be the good way to implement this? Delphi winapi callback link|improve this question asked Jun 1 '10 at 20:26FractalizeR8,39211043 91% accept rate.

I doubt this is in any way elegant but, IMO, the easiest is to convert the address of a method of a class to a procedure address and pass it to the winapi. Sure, it's a hack, but the VCL does the very same with classes. MakeObjectInstance, if only for a specific construct.. See this question for a source for this kind of implementaion and some other, more OO ways to handle the situation.

Future (Proc calls are very different in 64). I really doubt it. But there is no way to tell now.

– ChristianWimmer Jun 6 '10 at 11:21.

You can use static keyword for that. But it's available only in new Delphi versions. Like this: type TMyThread = class private // ... class function ThreadProc(Param: Pointer): DWord; stdcall; static; // Create; begin // ... FHandle := CreateThread(nil, 0, @ThreadProc, Self, 0, FID); end; class function TMyThread.

ThreadProc(Param: Pointer): DWord; begin Result := TMyThread(Param). Execute; end; function TMyThread. Execute: DWord; begin MessageBox(0, ' 'Information', MB_OK or MB_ICONINFORMATION); Result := 0; end; Here: ThreadProc is WinAPI callback routine.

It requires to have some form of custom argument, where you can pass Self. It can not access instance members. That's why it's just a wrapper for real callback (Execute), which is part of class and can access its fields and methods.

You can also get rid of the wrapper (ThreadProc), if you ensure that callback (Execute) will have the very same binary signature that required WinAPI callback. In the above example you can add "stdcall" to Execute and remove ThreadProc completely, passing @Execute to CreateThread. But it's a dangerous path.

– Alexander Jun 1 '10 at 22:32 Thank you, but I mentioned, that my class is not a singleton and there can be a plenty of this class' instances in the application. So, static method solution is not so good. Unless may be I store somewhere a list of method pointers needs to be called depending on something passed to callback.

– FractalizeR Jun 2 '10 at 7:13 @FractalizeR Ummm... why do you think that you can create only one instance? You can use any number of instances you want. Please, study my example more carefully.

The exact instance is saved. – Alexander Jun 2 '10 at 9:44 @Alexander - Not all api callbacks employ a "pass-back" parameter. How would you adapt this approach, say, for instance for a CBTProc (SetWindowsHookEx) callback?

– Sertac Akyuz Jun 2 '10 at 14:06 @Sertac Akyuz - @FractalizeR asked a specific question about ReadFileEx - and you CAN pass Self to ReadFileEx's callback (via hEvent). I've answered on that specific question only. If you ask different question (say, how do I do that with callback without custom parameter) - then this answer will not be applicable (obviosly).

– Alexander Jun 2 '10 at 14:31.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions