Search notes:

Accessing and calling DLLs from VBA: Calling back to VBA functions from the DLL

When using DLLs from Visual Basic for Applications, its also possible to call VBA functions from the DLL. The DLL needs declare a function pointer. The VBA code needs to pass the address of the function to be called with the addressOf operator.

dll.c

The DLL exports two functions. setCallbackFunction allows VBA to specify which function it wants to have called back. callCallbackFunction then actually calls the callback function.
//
//   cl /LD dll.c user32.lib OleAut32.lib /Fethe.dll /link /def:dll.def
//
#include <windows.h>

typedef int (WINAPI *callbackFunc_t)(int, BSTR);

callbackFunc_t callbackFunc;

__declspec(dllexport) void __stdcall setCallbackFunction(callbackFunc_t callbackFunc_) {
     callbackFunc = callbackFunc_;
}

__declspec(dllexport) int __stdcall callCallbackFunction(int i) {

    char*  txt    ;
    int    num    ;
    int    retVal ;
    int    wslen  ;
    BSTR   txtBstr;

    if      (i == 1) { num = 11; txt = "one"  ; }
    else if (i == 2) { num = 22; txt = "two"  ; }
    else if (i == 3) { num = 33; txt = "three"; }
    else             { num =  0; txt = "?"    ; }

    wslen = MultiByteToWideChar(CP_ACP, 0, txt, strlen(txt),       0,     0); txtBstr  = SysAllocStringLen(0, wslen);
            MultiByteToWideChar(CP_ACP, 0, txt, strlen(txt), txtBstr, wslen);

    retVal  = (*callbackFunc)(num, txtBstr);

    SysFreeString(txtBstr);

    return retVal;
}
Github repository VBA-calls-DLL, path: /callback/dll.c

call-the-dll.bas

This is the VBA code that lets the DLL call back its callback function.
option explicit

declare sub       setCallbackFunction lib "c:\github\VBA-calls-DLL\callback\the.dll" (byVal addrCallback as long)
declare function callCallbackFunction lib "c:\github\VBA-calls-DLL\callback\the.dll" (byVal i            as long) as long

sub main() ' {

    setCallbackFunction(vba.int(addressOf callback))

    debug.print "Return value for 1 = " & callCallbackFunction(1)
    debug.print "Return value for 2 = " & callCallbackFunction(2)
    debug.print "Return value for 3 = " & callCallbackFunction(3)
    debug.print "Return value for 4 = " & callCallbackFunction(4)

end sub ' }

function callBack(byVal num as long, byVal txt as string) as long ' {

    debug.print "Callback was called, num = " & num & ", txt = " & txt

    callBack = num + 5

end function ' }
Github repository VBA-calls-DLL, path: /callback/call-the-dll.bas

dll.def

LIBRARY the
EXPORTS
  setCallbackFunction
  callCallbackFunction
Github repository VBA-calls-DLL, path: /callback/dll.def

See also

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

Index