Gili
Gili

Reputation: 90043

How do I provide ReadFileEx()'s completion routine with context information?

Win32 ReadFileEx is defined as:

BOOL WINAPI ReadFileEx(
  __in       HANDLE hFile,
  __out_opt  LPVOID lpBuffer,
  __in       DWORD nNumberOfBytesToRead,
  __inout    LPOVERLAPPED lpOverlapped,
  __in_opt   LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

I am trying to figure out how to make the completion routine (the last argument) invoke a dynamic function pointer when the operation completes. There doesn't seem to be a way to pass in user-data. Any ideas?

Upvotes: 4

Views: 2053

Answers (3)

Fire Lancer
Fire Lancer

Reputation: 30145

Was doing some IO work today and noticed in the WSA and File read/write functions it is stated that the hEvent of the OVERLAPPED structure is not used if you are using a completion routine, e.g. from ReadFileEx

The ReadFileEx function ignores the OVERLAPPED structure's hEvent member. An application is free to use that member for its own purposes in the context of a ReadFileEx call. ReadFileEx signals completion of its read operation by calling, or queuing a call to, the completion routine pointed to by lpCompletionRoutine, so it does not need an event handle.

Upvotes: 3

Larry Osterman
Larry Osterman

Reputation: 16142

The lpOverlapped function passed into ReadFileEx is passed into the lpCompletionRoutine function.

You can embed the lpOverlapped in your own structure and then use that to find the pointer to your context:

struct ReadFileExContext
{ 
    OVERLAPPED _Overlapped; 
    LPVOID MyContext; 
}; 

Then in your callback function you cast the LPOVERLAPPED to a ReadFileContext and you're good to go.

Upvotes: 7

i_am_jorf
i_am_jorf

Reputation: 54600

You could use Thread Local Storage... Just create a slot and store a pointer to whatever data you want. Since lpCompletionRoutine runs on the calling thread, you should be fine.

Upvotes: -1

Related Questions