The information in this article applies to:
SUMMARYThe new AddressOF operator allows you to pass the Address of a Visual Basic procedure to a DLL for the purposes of providing a Callback function. However, Visual Basic does not let you make the callback directly from within BASIC code. This article provides a helper DLL that makes generic callback functionality available to BASIC. MORE INFORMATION
The usual way to use the callback mechanism is to write separate DLL
functions for each BASIC function prototype. This article details two
Visual C++ functions that provide a generic callback mechanism for any
BASIC function prototype. The functions work by manipulating the stack,
thus passing the parameters directly to the called function.
Visual C++ CodeThe following code was compiled using Microsoft Visual C++ 4.0 but should work with other compilers. This is in a standard DLL project with multi- threaded DLL libraries. The calling convention has no prolog code. If you're unsure, have the compiler generate an .ASM file, examine the output, and choose a different calling convention. You can ignore epilog code because it will never get executed.NOTE: This code is specific to the INTEL platform only. Callback.DEF
Callback.CPP
Visual Basic CodeThe function prototypes in BASIC are achieved by using the DECLARE statement because the BASIC compiler does no type checking on the DLL functions. The first argument needs to be a LONG with which to pass the address of the function to be called. Subsequent arguments and the function return type should match the callback function exactly.Sample Callback Function Declarations:The callback functions must reside in a standard .BAS module. They cannot reside in a Form or Class module:
Sample Declare StatementsThe declare statements can be anywhere. If in a Form or Class module, they need to be declared using Private Declare ...:
The use of "Callback" or "Callback2" depends on the function return type as explained in the Return Type table (below). Sample UsageThe callback functions can be called from anywhere in scope of the prototype Declare statement:
Return-type TableThe following table indicates which return types should use Callback and which should use Callback2 in their Declare statements.Two versions of the function are required. The first is for Sub routines and all Function prototypes whose return type occupies 8 bytes or less, including all object types and String. The second is for Function prototypes whose return argument is greater than 8 bytes, namely all Variants and those User-Defined Types whose length is greater than 8 bytes. The reason for this dichotomy is that Visual Basic can't return these large data types in a register. It passes the address of a pre-allocated structure as an implicit parameter on the stack, which the second callback function takes into account.
If you're unsure about which function to use with your user-defined type, you may have to try both functions and see which one works. The example below illustrates Types requiring both Callback and Callback2:
A Note About StringsBecause BASIC is calling a DLL, it will convert string parameters from UNICODE to ANSI when calling, and back to UNICODE when returning. If the function returns a String, it undergoes the ANSI to UNICODE conversion process also. The callback function receives the converted (ANSI) string, which can present problems. This also applies to Strings in User-Defined types. There are several ways to deal with this problem:
NOTE: You don't have to use the Callback2 function unless you return a Variant or large User-Defined Type as the function result. Using Variants and User-defined types as function arguments has no bearing on which DLL function to use in your Declare statement. Other NotesIn many cases, you can get similar functionality completely in BASIC by using a SELECT CASE statement to call multiple implementations of the same prototype, or by using callback objects. The main area where the all-BASIC solution won't apply is using components that require calling back into your code and that need to call a function rather than an object.(c) Microsoft Corporation 1997. All Rights Reserved. Contributions by Malcolm Stewart, Microsoft Corporation (c) Microsoft Corporation 1997. All Rights Reserved. Contributions by Richard Ault, Microsoft Corporation Additional query words: kbVBp500 kbVBp600 kbVBp kbdsd kbDSupport kbNoKeyWord
Keywords : kbGrpVB |
Last Reviewed: January 5, 2000 © 2000 Microsoft Corporation. All rights reserved. Terms of Use. |