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;
}
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 ' }