I am trying to figure out how to declare a Win32 API function which
takes a void-returning callback function as a parameter in Visual
Basic 6.
I'm writing a program that uses the Win32 API for asynchronous file
I/O, specifically the ReadFileEx() function. To use this in Visual
Basic 6 I need to declare it:
Public Declare Function ReadFileEx Lib "kernel32" _
(ByVal hFile As Long, lpBuffer As Any, _
ByVal nNumberOfBytesToRead As Long, _
lpOverlapped As OverLapped, _
ByVal lpCompletionRoutine As Long) As Long
The problem I am running into is that the callback function parameter
(lpCompletionRoutine) will be a function that returns void, rather
than a long (as it is specified above). Visual Basic 6 has no void
type, functions that do not return anything are declared with "Sub"
(which doesn't work as a return type, unfortunately). When I run my
code with the declaration above, the function is called successfully,
but the first two parameters passed to my callback are invalid and
cause the whole program to crash when accessed.
How can I change the ReadFileEx declaration above to specify the
return type of the callback function as void? |
Request for Question Clarification by
joseleon-ga
on
10 Jun 2002 10:09 PDT
Hello:
A function that return void, returns nothing which is equivalent to
SUB in Visual Basic, you say:
"functions that do not return anything are declared with "Sub"
(which doesn't work as a return type, unfortunately)"
Could you please post the source code of the completion routine you
are using?, Have you tried to use a Sub instead a Function?, Have you
declared the completion routine to follow the stdcall convention of
the Windows API?
Please, answer this questions and I will try to answer yours.
Regards.
|
Clarification of Question by
theoldpond-ga
on
10 Jun 2002 10:50 PDT
Here are some code chunks that hopefully will clarify things:
First I declare the Win32 API function I want to use:
Public Declare Function ReadFileEx Lib "kernel32" ( _
ByVal hFile As Long, lpBuffer As Any, _
ByVal nNumberOfBytesToRead As Long, _
lpOverlapped As OverLapped, _
ByVal lpCompletionRoutine As Long _
) As Long
(note that I'm declaring lpCompletionRoutine as a Long. . . I suspect
that this is incorrect)
Now, I call ReadFileEx():
ReturnValue = ReadFileEx(pHandle, pBuffer, pLength, _
pOverlapped, _
AddressOf ReadFileExCallback)
Note that the final parameter is a pointer to my callback function
which
looks like this:
Public Sub ReadFileExCallback(ErrorCode As Long, _
BytesRead As Long, _
pOverlapped As OverLapped)
... Function code. . .
End Function
I wrote ReadFileExCallback to match the FileIoCompletionRoutine
prototype
that ReadFileEx expects:
VOID CALLBACK FileIOCompletionRoutine(
DWORD dwErrorCode, // completion code
DWORD dwNumberOfBytesTransfered, // number of bytes transferred
LPOVERLAPPED lpOverlapped // pointer to structure with I/O
// information
);
ReadFileExCallback is a Sub to match the return type of the
FileIOCompletionRoutine prototype. But when I specified the function
pointer parameter in my declaration of ReadFileEx I couldn't specify
it as a void or as a sub (which are not a Visual Basic data types).
So my question is, what type should I put in the fourth parameter of
the ReadFileEx() declaration instead of Long?
To answer your questions:
-See code above
-The callback is a sub (that's the problem)
-I'm not quite sure how to use the stdcall convention in this case
|
Request for Question Clarification by
j_philipp-ga
on
10 Jun 2002 11:15 PDT
Hello Theoldpond,
did you try to pass it as "AddressOf"?
|
Clarification of Question by
theoldpond-ga
on
10 Jun 2002 11:40 PDT
Hi j_philipp,
Unfortunately, "AddressOf" is not a valid data type in VB. Thanks for
the suggestion, though.
|