Google Answers Logo
View Question
 
Q: Declaring Win32 API functions with void callback parameters ( Answered 4 out of 5 stars,   0 Comments )
Question  
Subject: Declaring Win32 API functions with void callback parameters
Category: Computers > Programming
Asked by: theoldpond-ga
List Price: $15.00
Posted: 10 Jun 2002 08:31 PDT
Expires: 17 Jun 2002 08:31 PDT
Question ID: 24117
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.
Answer  
Subject: Re: Declaring Win32 API functions with void callback parameters
Answered By: davidmaymudes-ga on 10 Jun 2002 22:48 PDT
Rated:4 out of 5 stars
 
I think your current declaration is correct; see for example
http://www.mvps.org/vbnet/index.html?code/enums/enumrestorewin.htm
which uses the same method of declaring the callback parameter as
"Long".

I also found a product support article
(http://support.microsoft.com/default.aspx?scid=kb;EN-US;q189850)
which discusses using callbacks with WinINet APIs from Visual Basic
and, after explaining some tricks to make it work, says "At this
point, it should be noted that the necessary skill set to accomplish
asynchronous WinInet APIs within Visual Basic will be the same as the
skill set needed to write a C/C++ application using WinInet in
asynchronous mode. This makes using WinInet APIs in Visual Basic
asynchronously an undesirable option."

I would tend to say the same thing about ReadFileEx: if you're really
writing a multithreaded program that needs the performance gains from
overlapped I/O, Visual Basic may not be the proper tool for the job.

If there's a specific reason you really want to be doing this, I'll
try to help further, though; let me know.  You mentioned that using
the "first two" parameters to your callback function causes your
program to crash....  did you really mean that the lpOverlapped
parameter is broken, and not the other two?  I can't imagine how
looking at either the error code or BytesRead could cause a crash.

So I think that the problem isn't in the declaration, but somewhere
else.  Sorry I can't be more directly helpful, but I hope this
information is useful to you.

--David

Search terms used: "readfileex visual basic" "void callback visual
basic"
theoldpond-ga rated this answer:4 out of 5 stars

Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy