0

What is the correct VB6 declaration for this C++ function?

LPCWSTR* MW_ListReaders(_ULONG Context, int* NumberOfReaders);

The following gave me "Bad DLL calling convention":

Private Declare Function ListReaders Lib "MyDLL.dll" (ByVal Context As Long, _
                                                    ByRef NumberOfReaders As Integer) As Long
GSerg
  • 76,472
  • 17
  • 159
  • 346
user2334678
  • 1
  • 1
  • 1

2 Answers2

5

There is no calling convention specified in that C++ declaration. Most C/C++ compilers default to __cdecl. If the function does actually use __cdecl then you will not be able to call it in VB6:

How To Call C Functions That Use the _cdecl Calling Convention

It is not possible to directly call a C function in a DLL if that function uses the _cdecl calling convention. This is because Visual Basic uses the _stdcall calling convention for calling functions. This is a problem because if _cdecl is used, the calling function is responsible for cleaning up the stack. However, if _stdcall is used, the called function is responsible for cleaning up the stack.

NOTE: An .EXE file created in Visual Basic will allow you to call a DLL function that has been declared with the _cdecl calling convention without an error. It is only when you try to call such a function when running a program from the Visual Basic IDE, that Visual Basic generates the following error:

Run-time Error '49': Bad DLL Calling Convention

The fact that the EXE version allows you to call such functions has been confirmed to be a bug by Microsoft. You should not rely on this behavior as this might change in future versions of Visual Basic.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • The important word from the quoted documentation is *directly*. You can call a `cdecl` function from VB6 if it's [described in a type library](https://stackoverflow.com/a/5196051/11683). – GSerg Apr 24 '18 at 11:02
0

In addition to Remy's answer, you have also got the Vb declaration slightly wrong:

Private Declare Function ListReaders Lib "MyDLL.dll" (ByVal Context As Long, ByRef NumberOfReaders As Long) As Long

"Integer" is a 2 byte integer in vb.

Mark Bertenshaw
  • 5,594
  • 2
  • 27
  • 40