0

I need to write some functions in C for someone else's VB6 project (that being outdated is beyond the scope of this question).

During initial tests, I could not get the calls to work. I have supplied a .def file, I tried to use __declspec(dllexport), stdcall and WINAPI calling conventions. Each call I get an error message in VB6 saying "bad dll calling convention."

Win32 C function prototypes:

long WINAPI BitmapFile_Open(char *pszFileName);
void WINAPI BitmapFile_Close(long bmf);

note in the above I have tried several other calling conventions, including __declspec(dllexport) and stdcall, and neither work.

Def file:

LIBRARY ImageLib
EXPORTS
BitmapFile_Open @1
BitmapFile_Open @2

VB Global Module:

 Declare Function BitmapFile_Open Lib "ImageLib.dll" (ByVal fileName As String) As Long
 Declare Function BitmapFile_Close Lib "ImageLib.dll" (ByVal bmFile As Long)

VB Code:

Dim myFile As Long
myFile = BitmapFile_Open("test.bmp")
BitmapFile_Close (myFile)

Also note that in the original functions, the bmFile is actually an address (pointer to a structure) but in VB it will be represented as long. However, since VB6 doesn't support pointers, I am casting from long in the C code. I hope you can understand what I'm trying to get at here. It has nothing to do with the error that is occurring. Any help is appreciated.

Edit: I have used a dependency walker to determine that the functions are indeed being exported. VB6 is just not calling them without error.

oldSkool
  • 1,212
  • 5
  • 14
  • 29
  • 2
    You may want to give [Dan Appleman's Visual Basic Programmer's Guide to the Win32 API](http://www.amazon.com/Applemans-Visual-Basic-Programmers-Guide/dp/0672315904/ref=sr_1_1?s=books&ie=UTF8&qid=1327723110&sr=1-1) a look. I know you are not trying to interface to Windows itself, but he does do some explaining on how to figure out the `Declare Function` – Mark Hall Jan 28 '12 at 03:59
  • Try it without the .def file so the export doesn't get renamed. – Hans Passant Jan 28 '12 at 12:01

3 Answers3

3

BitmapFile_Close should be declared as a Sub in the VB6. I can't see anything else wrong.

Look at the Microsoft advice on writing C DLLs to be called from VB. Originally released with VB5 but still relevant to VB6.

MarkJ
  • 30,070
  • 5
  • 68
  • 111
  • Additionally, if `the bmFile is actually an address (pointer to a structure)`, just declare the structure in VB and declare `Declare Sub BitmapFile_Close Lib "ImageLib.dll" (bmFile As somestructure)`. That is provided you are going to use the contents of the structure, of course. Also, [remove the parentheses](http://stackoverflow.com/a/8070104/11683) from the `Close` call. – GSerg Jan 28 '12 at 11:31
0

Try removing the ByVal from the arguments in question (inside the declaration section) one by one, then test and try removing for all arguments then test again. Do the incremental tests and report back if you can. That should do the trick!

Erx_VB.NExT.Coder
  • 4,838
  • 10
  • 56
  • 92
  • to the person who negative voted, the most common cause of a "bad dll calling convention" error is either not having a ByVal in the dec or having one that isn't needed. in other words passing by reference (and visa versa) can have adverse effects due to the ansi\unicode issue between vb and C... as i've just solved a problem based on this factor alone, you can check it out here... http://stackoverflow.com/questions/9047721/how-to-do-public-declare-ansi-function-in-vb6 – Erx_VB.NExT.Coder Jan 28 '12 at 23:48
  • In this particular question OP shows both C and VB signatures. It is therefore easy to see that the parameters are properly declared. There is no guessing here as to whether or not a `ByVal` should be removed or added. As [noted by MarkJ](http://stackoverflow.com/a/9043697/11683), the only problem with the declaration is `Function` instead of `Sub`, which imbalances the stack indeed, as VB expects to see a Variant returned. – GSerg Jan 29 '12 at 02:19
0

Use MIDL to generate a type library for your DLL, then VB6 can use its type information instead of Declare Function routines.

For global functions, I seem to recall that you want a library and module defined.

See VB - Linking a DLL in implicit way

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720