Search notes:

Accessing and calling DLLs from VBA: passing null pointers

This is a test that I used to check if I can pass null pointers to a DLL from Visual Basic for Applications.
This is apparently possible if the pointer argument is declared byRef and the special type any in the VBA declare statement.

dll.c

This is the c source for the DLL. It has one function (or entry point): asAny. The function takes one argument: a simple pointer (void*).
The function returns false if the pointer was a null pointer and true (or more exactly -1 which seems to be the VBA equivalent for true) otherwise.
Additionally, when the pointer was not null, it is assumed to be a pointer to a wstr (or an OLECHAR (?)). A message box then prints the address that the pointer points at as well as the string value at that address.
#include <windows.h>

__declspec(dllexport) int __stdcall asAny(void* pointer) {

    char buf[200];

    if (! pointer) {
     // return 0 (false) to indicate that pointer was a null pointer
        return 0;
    }
  
    wsprintfA(buf, "pointer = %p, *pointer = %s", pointer, (wchar_t*) pointer); 
    MessageBoxA(0, buf, "asAny", 0);
  
 // return -1 (true) to indicate that ptrFoo was not a null pointer
    return -1;

}
Github repository VBA-calls-DLL, path: /pass-null-pointers/dll.c

call-the-dll.bas

This is the source code that calls the DLL.
The argument pointer of the DLL function asAny is declared with the special type any that seems to be necessary in order to be able to pass null pointers.
option explicit

declare ptrSafe function asAny        _
        lib "the.dll" (               _
               byVal  pointer as any  _
        ) as boolean

sub main()

    if asAny( nothing ) then
       debug.print("asAny( nothing )      returned true" )
    else
       debug.print("asAny( nothing )      returned false")
    end if

  ' --------------------------------------------------------

  ' if asAny( 0 ) then --> Compilie error: Type mismatch

  ' --------------------------------------------------------

    if asAny( vbNullString ) then
       debug.print("asAny( vbNullString ) returned true" )
    else
       debug.print("asAny( vbNullString ) returned false")
    end if

  ' --------------------------------------------------------

    dim text as string
    text = "Hello World"

    if asAny( text ) then
       debug.print("asAny( text )         returned true" )
    else
       debug.print("asAny( text )         returned false")
    end if

end sub
Github repository VBA-calls-DLL, path: /pass-null-pointers/call-the-dll.bas

Output

The VBA program calls asAny three times.
The first time, it calls it with nothing. This is passed as null pointer to the DLL and consequently, the DLL returns false.
The second time, the function is called with the special constant vbNullString. Also this value is passed as null pointer to the DLL and again, the function return false.
In the third time, the function is called with a string. This is passed as an actual pointer. Hence, the DLL displays a message box and returns true.

dll.def

This is the def file that is needed create a DLL with undecorated names when compiling with the Microsoft cl compiler.
LIBRARY the
EXPORTS
  asAny
Github repository VBA-calls-DLL, path: /pass-null-pointers/dll.def

See also

Accessing and calling DLLs from VBA (Visual Basic for Applications)

Index