c++excelvbadllstdcall

Importing C++ DLL to Excel(VBA) gives 49 or 453 Error


Its my first time writing DLLs and as the title suggests I am trying to import my DLL in Excel however I ran into a brick Wall with stdcall written on it. Here is a minimal example of my problem: My C++ DLL defines the functions

extern "C" __declspec(dllexport) BOOL testBool1() {
    return true;
}

extern "C" __declspec(dllexport) BOOL __stdcall testBool2() {
    return true;
}


extern "C" __declspec(dllexport) BOOL __stdcall testBool3(BOOL a) {
    return a;
}

extern "C" __declspec(dllexport) BOOL testBool4(BOOL a) {
    return a;
}

in VBA I try to import them using

Declare Function testBool1 Lib "MyDLL" () As Boolean
Declare Function testBool2 Lib "MyDLL" () As Boolean
Declare Function testBool3 Lib "MyDLL" (ByVal a As Boolean) As Boolean
Declare Function testBool4 Lib "MyDLL" (ByVal a As Boolean) As Boolean

Sub Test()
  testBool1
  testBool2
  testBool3 (True)
  testBool4 (True)
End Sub

What I think is going on is:

What can i do to fix this? In my problem I can not change the VBA code only the C++ code.

Update: it seems like the c++ compiler is adding a '_' to the functions with __stdcall, the DLL contains ".testBool1._testBool2@0._testBool3@4.testBool4". This only happens when compiling to a 32 bit DLL. With a 64 Bit DLL there should be no problem, unfortunately I do not have a 64 Bit Excel right now to verify.


Solution

  • When compiling for a 32-bit target (which your use of stdcall implies), the compiler will decorate the names of the exported functions absent instructions to the contrary. For a cdecl function it will prepend an underscore, and for stdcall it will additionally append an @ symbol and the number of bytes of arguments (a rudimentary way of making sure you don't use mismatched declarations and trash the stack).

    If you had control of the VBA, you could use the Alias directive to tell it the decorated names. Without control of the VBA, the only alternative is to use a module definition file, which will tell the linker to override the standard name decoration.

    The definition file will look like this:

    LIBRARY "MyDLL.dll"
    
    EXPORTS
        testBool1
        testBool2
        testBool3
        testBool4
    

    There are quite a few additional things that can be done with module definition files which aren't relevant to your application. The format is documented by Microsoft here: https://learn.microsoft.com/en-us/cpp/build/reference/module-definition-dot-def-files?view=msvc-170

    Note that accounting for name decoration is only relevant for 32-bit compiling, as in 64-bit stdcall was eliminated and name decorations are not included for C-format function names. However, it won't hurt to continue to include the module definition file.