admin管理员组

文章数量:1355660

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
  • testBool1 works just fine
  • testBool2 gives a 453 error (Can't find DLL entry point)
  • testBool3 gives a 49 error (Bad DLL calling convention)
  • testBool4 gives a 453 error (Can't find DLL entry point)

What I think is going on is:

  • Excel expects the stdcall convention. However if the function has no parameters it doesnt matter whether its stdcall or cdecl, therefore testBool1 works and testBool3 does not.
  • Putting the __stdcall in C++ prevents VBA from finding the function, hence the 453 Error for testBool2 and testBool4.

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@[email protected]". 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.

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
  • testBool1 works just fine
  • testBool2 gives a 453 error (Can't find DLL entry point)
  • testBool3 gives a 49 error (Bad DLL calling convention)
  • testBool4 gives a 453 error (Can't find DLL entry point)

What I think is going on is:

  • Excel expects the stdcall convention. However if the function has no parameters it doesnt matter whether its stdcall or cdecl, therefore testBool1 works and testBool3 does not.
  • Putting the __stdcall in C++ prevents VBA from finding the function, hence the 453 Error for testBool2 and testBool4.

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@[email protected]". 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.

Share Improve this question edited Mar 28 at 14:15 user30093107 asked Mar 28 at 13:25 user30093107user30093107 133 bronze badges 3
  • 1 I think you will need to use an export definition file to force undecorated names of functions. cdecl will normally prepend an underscore, stdcall will normally append an @ character followed by the number of bytes of arguments (and note that stdcall is only applicable for 32-bit and goes away for 64-bit). – Craig Commented Mar 28 at 14:10
  • 1 Note that BOOL is four bytes and Boolean is two. They also have different representation of TRUE (1 and -1 respectively). And you are using parentheses when you shouldn't. – GSerg Commented Mar 28 at 14:49
  • 1 Re BOOL vs Boolean, I believe the correct representation of the VB Boolean type in C++ is VARIANT_BOOL, where the true value is VARIANT_TRUE. – Craig Commented Mar 28 at 15:23
Add a comment  | 

2 Answers 2

Reset to default 1

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/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.

As Craig said creating a .def solves the problem

LIBRARY MyDll
EXPORTS
    testBool1
    testBool2
    testBool3
    testBool4

You can use

dumpbin /EXPORTS myDll.dll

to get a list of the function names (In Visual Studio I can run the command in Tools->Command Line -> Developer Command Prompt).

本文标签: Importing C DLL to Excel(VBA) gives 49 or 453 ErrorStack Overflow