Passing arguments by value and by reference
By default, Visual Basic passes all arguments by reference. This means that instead of passing the actual value of the argument, Visual Basic passes a 32-bit address where the value is stored. This is very convenient because this is the same convention used by Fortran. Although you do not need to include the ByRef keyword in your Declare statements, you may want to do so to document how the data is passed.
With some Fortran compilers, you can change the standard convention for arguments and create subroutines that receive arguments by value. This means the subroutine expects the actual value, instead of its memory location. If you pass an argument by reference to a procedure that expects an argument passed by value, the procedure receives incorrect data and fails to work properly.
To pass an argument by value, place the ByVal keyword in front of the argument declaration in the Declare statement. For example, the InvertRect procedure accepts its first argument by value and its second by reference:
Declare Function InvertRect Lib "user32" Alias "InvertRectA" (ByVal hdc As Long, lpRect As RECT) As Long
You can also use the ByVal keyword when you call the procedure.
Some Visual Basic arguments can only be passed by reference. Arrays and User Defined Types (UDTs) are always passed by reference. Attempting to pass an array or UDT by value will result in an error message by the Visual Basic compiler/interpreter.
String arguments are also a special case. Independently of whether you pass the string by value or by reference, Visual Basic always passes a BString handle (which is itself a pointer to the string). If you pass the string by value, your subroutine gets the handle directly. If you pass the string by reference, the receiving subroutine gets a memory address where the handle is stored.
Passing Basic data types (Integer, Boolean and Real types)