VB Error: "Bad DLL Calling Convention"
Author |
Message |
ohay #1 / 22
|
 VB Error: "Bad DLL Calling Convention"
Hi, I am trying to call a VC++ DLL from VB. The VC++ function prototype is: DLogInit ( const char * dS, int level) In my VB program, I have the following Declare: Private Declare Sub DbLogInit Lib "DB.dll" (ByRef bTheDSN() As Byte, ByVal iLevel As Integer) And, I call DBLogInit by: Dim bDSN(0 to 100) as byte . . bDSN(0) = Asc("D") bDSN(1) = Asc("S") bDSN(2) = Asc("N") bDSN(3) = 0 In other words, DBLogInit is expecting an array of chars, so in my VB program, I am calling DBLogInit with an array of bytes that I fill in a byte at a time. When I try to execute the above, I am getting a "Badd DLL Calling Convention" error. Can anyone tell me what I'm doing wrong, or suggest how I should be doing this? Thanks, Jim
|
Mon, 24 Oct 2005 07:22:05 GMT |
|
 |
Tom Shelto #2 / 22
|
 VB Error: "Bad DLL Calling Convention"
Quote:
> Hi, > I am trying to call a VC++ DLL from VB. > The VC++ function prototype is: > DLogInit ( const char * dS, int level) > In my VB program, I have the following Declare: > Private Declare Sub DbLogInit Lib "DB.dll" (ByRef bTheDSN() As Byte, > ByVal iLevel As Integer) > And, I call DBLogInit by: > Dim bDSN(0 to 100) as byte > . > . > bDSN(0) = Asc("D") > bDSN(1) = Asc("S") > bDSN(2) = Asc("N") > bDSN(3) = 0 > In other words, DBLogInit is expecting an array of chars, so in my VB > program, I am calling DBLogInit with an array of bytes that I fill in a > byte at a time. > When I try to execute the above, I am getting a "Badd DLL Calling > Convention" error. > Can anyone tell me what I'm doing wrong, or suggest how I should be > doing this? > Thanks, > Jim
Off the top of my head, I would have to say that the problem is with the calling convention used by the dll. Functions created with VC++ default to __cdecl, but VB can't use it. VB expects the function to use __stdcall. So, if you have control of the source change the calling convention and use a .DEF file to specify the exports (that is the easiest way so that you avoid the name mangling that __stdcall causes). If you don't control the source, then you will need to look into one of the hacks to call __cdecl functions from VB. There is a whole section on this in "Advanced Visual Basic 6" by Mat Curland. Tom Shelton
|
Mon, 24 Oct 2005 07:30:30 GMT |
|
 |
ohay #3 / 22
|
 VB Error: "Bad DLL Calling Convention"
Hi, I forgot to mention that I'm pretty sure that the VC++ function type is right to allow this to be called from my VB program, but I don't have the source for the DLL so I'm not sure exactly what it is and left it out of my earlier post. Jim Quote:
> Hi, > I am trying to call a VC++ DLL from VB. > The VC++ function prototype is: > DLogInit ( const char * dS, int level) > In my VB program, I have the following Declare: > Private Declare Sub DbLogInit Lib "DB.dll" (ByRef bTheDSN() As Byte, > ByVal iLevel As Integer) > And, I call DBLogInit by: > Dim bDSN(0 to 100) as byte > . > . > bDSN(0) = Asc("D") > bDSN(1) = Asc("S") > bDSN(2) = Asc("N") > bDSN(3) = 0 > In other words, DBLogInit is expecting an array of chars, so in my VB > program, I am calling DBLogInit with an array of bytes that I fill in a > byte at a time. > When I try to execute the above, I am getting a "Badd DLL Calling > Convention" error. > Can anyone tell me what I'm doing wrong, or suggest how I should be > doing this? > Thanks, > Jim
|
Mon, 24 Oct 2005 07:29:23 GMT |
|
 |
Tom Shelto #4 / 22
|
 VB Error: "Bad DLL Calling Convention"
Quote:
> Hi, > I forgot to mention that I'm pretty sure that the VC++ function type is > right to allow this to be called from my VB program, but I don't have > the source for the DLL so I'm not sure exactly what it is and left it > out of my earlier post. > Jim
> > Hi, > > I am trying to call a VC++ DLL from VB. > > The VC++ function prototype is: > > DLogInit ( const char * dS, int level) > > In my VB program, I have the following Declare: > > Private Declare Sub DbLogInit Lib "DB.dll" (ByRef bTheDSN() As Byte, > > ByVal iLevel As Integer)
Well if what you say is true, and it is the right calling convention you will want to change your declaration to look like this... Private Declare Sub DbLogInit Lib "DB.dll" (ByVal dS As String, ByVal level As Long) Dim DSN As String DSN = "DSN" Call DbLogInit(DSN, whatever) VB will automatically convert the string to an ANSI string and it will be null terminated, so you don't have to send in the byte array. Further, an int in C is 32-bit, which in VB.CLASSIC is a Long. This may cause your problem because the error your getting is VB's polite method of telling you that the stack has been screwed... Tom Shelton Quote: > > And, I call DBLogInit by: > > Dim bDSN(0 to 100) as byte > > . > > . > > bDSN(0) = Asc("D") > > bDSN(1) = Asc("S") > > bDSN(2) = Asc("N") > > bDSN(3) = 0 > > In other words, DBLogInit is expecting an array of chars, so in my VB > > program, I am calling DBLogInit with an array of bytes that I fill in a > > byte at a time. > > When I try to execute the above, I am getting a "Badd DLL Calling > > Convention" error. > > Can anyone tell me what I'm doing wrong, or suggest how I should be > > doing this? > > Thanks, > > Jim
|
Mon, 24 Oct 2005 07:39:13 GMT |
|
 |
ohay #5 / 22
|
 VB Error: "Bad DLL Calling Convention"
Tom, Thanks. You may be right, but I'm running into a strange problem with VB.... While trying to figure out what's going on, I ended up writing a small VC++ DLL, with the right function prototype to be called from VB. Then I wrote a small VB program that first calls my test DLL, then calls a function in the original DLL I was trying to work with, i.e., my test VB program looks like: i = MyDLL("DSN", whatever) i = DBLogInit("DSN" whatever) In MyDLL function, I do a couple of MessageBoxes, just to make sure that the string param is being passed ok, and that works. Ok, so, when I run test VB program in the VB IDE, it does the MyDLL function ok, then I get the "Bad DLL Calling Convention" error. BUT, if I compile my test VB program into an EXE, and then run the EXE, it does the MyDLL function, and then SEEMS TO JUST RUN THROUGH THE DBLogInit call without ANY ERROR message!!! Any idea what's going on? Why would I not get an error message when I run the EXE vs. getting error message if I run in the IDE?? Jim Quote:
> > Hi, > > I am trying to call a VC++ DLL from VB. > > The VC++ function prototype is: > > DLogInit ( const char * dS, int level) > > In my VB program, I have the following Declare: > > Private Declare Sub DbLogInit Lib "DB.dll" (ByRef bTheDSN() As Byte, > > ByVal iLevel As Integer) > > And, I call DBLogInit by: > > Dim bDSN(0 to 100) as byte > > . > > . > > bDSN(0) = Asc("D") > > bDSN(1) = Asc("S") > > bDSN(2) = Asc("N") > > bDSN(3) = 0 > > In other words, DBLogInit is expecting an array of chars, so in my VB > > program, I am calling DBLogInit with an array of bytes that I fill in a > > byte at a time. > > When I try to execute the above, I am getting a "Badd DLL Calling > > Convention" error. > > Can anyone tell me what I'm doing wrong, or suggest how I should be > > doing this? > > Thanks, > > Jim > Off the top of my head, I would have to say that the problem is with the > calling convention used by the dll. Functions created with VC++ default to > __cdecl, but VB can't use it. VB expects the function to use __stdcall. > So, if you have control of the source change the calling convention and use > a .DEF file to specify the exports (that is the easiest way so that you > avoid the name mangling that __stdcall causes). If you don't control the > source, then you will need to look into one of the hacks to call __cdecl > functions from VB. There is a whole section on this in "Advanced Visual > Basic 6" by Mat Curland. > Tom Shelton
|
Mon, 24 Oct 2005 10:15:35 GMT |
|
 |
Frank Ad #6 / 22
|
 VB Error: "Bad DLL Calling Convention"
You may be running into the mysteries of Windows programming. However, rest assured if your C functions are not declared with _stdcall it will fail. Exporting them without using the def file does indeed lead to some interesting problems, so i'd be taking Tom's advice (he is not very good at this stuff, but he does get lucky all the time <g>) and try again using the correct approach. If you still have problems let's see the code on both sides, and maybe we can spot something ? Quote: >Tom, >Thanks. You may be right, but I'm running into a strange problem with >VB.... >While trying to figure out what's going on, I ended up writing a small >VC++ DLL, with the right function prototype to be called from VB. >Then I wrote a small VB program that first calls my test DLL, then calls >a function in the original DLL I was trying to work with, i.e., my test >VB program looks like: >i = MyDLL("DSN", whatever) >i = DBLogInit("DSN" whatever) >In MyDLL function, I do a couple of MessageBoxes, just to make sure that >the string param is being passed ok, and that works. >Ok, so, when I run test VB program in the VB IDE, it does the MyDLL >function ok, then I get the "Bad DLL Calling Convention" error. >BUT, if I compile my test VB program into an EXE, and then run the EXE, >it does the MyDLL function, and then SEEMS TO JUST RUN THROUGH THE >DBLogInit call without ANY ERROR message!!! >Any idea what's going on? Why would I not get an error message when I >run the EXE vs. getting error message if I run in the IDE?? >Jim
-- Regards, Frank
|
Mon, 24 Oct 2005 12:56:19 GMT |
|
 |
ohay #7 / 22
|
 VB Error: "Bad DLL Calling Convention"
Frank, Thanks for the response. Actually, it turns out that I have indirect control and access to the DLLs under discussion, but the problem is that these same DLLs are already being used by a BUNCH of VC++ programs. Even if I could get the functions changed to _stdcall, then it seems that would break all of the VC++ programs :(. I happen to have a copy of Matt Curland's book, along with the CD, so I'm going to take a look at his CDECLFunctionDelegator.bas tonight/tomorrow. By any chance, do you or anyone else here have a simple example of using the CDECLFunctionDelegator, something along the lines that I need (calling a function with prototype x(string, int)? Thanks again, Jim Quote:
> You may be running into the mysteries of Windows programming. However, > rest assured if your C functions are not declared with _stdcall it > will fail. Exporting them without using the def file does indeed lead > to some interesting problems, so i'd be taking Tom's advice (he is not > very good at this stuff, but he does get lucky all the time <g>) and > try again using the correct approach. > If you still have problems let's see the code on both sides, and maybe > we can spot something ? > >Tom, > >Thanks. You may be right, but I'm running into a strange problem with > >VB.... > >While trying to figure out what's going on, I ended up writing a small > >VC++ DLL, with the right function prototype to be called from VB. > >Then I wrote a small VB program that first calls my test DLL, then calls > >a function in the original DLL I was trying to work with, i.e., my test > >VB program looks like: > >i = MyDLL("DSN", whatever) > >i = DBLogInit("DSN" whatever) > >In MyDLL function, I do a couple of MessageBoxes, just to make sure that > >the string param is being passed ok, and that works. > >Ok, so, when I run test VB program in the VB IDE, it does the MyDLL > >function ok, then I get the "Bad DLL Calling Convention" error. > >BUT, if I compile my test VB program into an EXE, and then run the EXE, > >it does the MyDLL function, and then SEEMS TO JUST RUN THROUGH THE > >DBLogInit call without ANY ERROR message!!! > >Any idea what's going on? Why would I not get an error message when I > >run the EXE vs. getting error message if I run in the IDE?? > >Jim > -- > Regards, Frank
|
Mon, 24 Oct 2005 13:24:40 GMT |
|
 |
J Fren #8 / 22
|
 VB Error: "Bad DLL Calling Convention"
<snip> Quote: >Ok, so, when I run test VB program in the VB IDE, it does the MyDLL >function ok, then I get the "Bad DLL Calling Convention" error. >BUT, if I compile my test VB program into an EXE, and then run the EXE, >it does the MyDLL function, and then SEEMS TO JUST RUN THROUGH THE >DBLogInit call without ANY ERROR message!!! >Any idea what's going on? Why would I not get an error message when I >run the EXE vs. getting error message if I run in the IDE??
<snip> You are almost certainly running different versions of the DLL In the IDE VB (stupidly) looks for DLLs first in the VB Path When compiled it looks first in App.Path To fix this do : ChDir App.Path as the very first thing in your program eg: Form_Load or Sub Main()
|
Mon, 24 Oct 2005 14:52:41 GMT |
|
 |
Dag Sund #9 / 22
|
 VB Error: "Bad DLL Calling Convention"
Quote:
> Frank, > Thanks for the response. Actually, it turns out that I have indirect > control and access to the DLLs under discussion, but the problem is that > these same DLLs are already being used by a BUNCH of VC++ programs. > Even if I could get the functions changed to _stdcall, then it seems > that would break all of the VC++ programs :(.
Then write a wrapper-dll in C++, Using _stdcall, which in its turn calls the problem-dll. You use the Wrapper-dll, and keep the C++ guys happy letting them continue using the old one. <snipped /> -- Dag.
|
Mon, 24 Oct 2005 15:39:51 GMT |
|
 |
ohay #10 / 22
|
 VB Error: "Bad DLL Calling Convention"
Dag, Thanks. I've been looking into that for a few hours now :). Actually, I've started working on a COM (DLL) wrapper, rather than a C-type wrapper. I was hoping to avoid doing a wrapper, mainly because of maintenance issues later. Now that you mention it though, a "straight C-type" wrapper might be easier, as I wouldn't have to keep fighting with the ATL types? Jim Quote:
> > Frank, > > Thanks for the response. Actually, it turns out that I have indirect > > control and access to the DLLs under discussion, but the problem is that > > these same DLLs are already being used by a BUNCH of VC++ programs. > > Even if I could get the functions changed to _stdcall, then it seems > > that would break all of the VC++ programs :(. > Then write a wrapper-dll in C++, Using _stdcall, which in its turn calls > the problem-dll. > You use the Wrapper-dll, and keep the C++ guys happy letting them continue > using the old one. > <snipped /> > -- > Dag.
|
Mon, 24 Oct 2005 15:44:37 GMT |
|
 |
Murphy McCaule #11 / 22
|
 VB Error: "Bad DLL Calling Convention"
VB actually can call cdecl functions natively with no "hacks" required -- just not if you declare them with the Declare statement. If you define them in a Type Library (which can be compiled with MKTYPLIB, which is on the VB CD), and reference the compiled type library in your VB project -- you can just call them. You should be able to find information about this on the net, or ask for more help here. As to why you get the error message in the IDE but not when compiled -- I don't find this suprising. It could happen for many reasons, and I've had it happen to me. I imagine that when compiled, the stack isn't checked after the function returns. Doing so would just slow down the program, and the problem should theoretically be discovered during debugging (in the IDE) anyway. So the stack is probably just being silently corrupted. This has been discussed in other replies, but your VB declare was wrong. ... Quote: > DLogInit ( const char * dS, int level) ... > Private Declare Sub DbLogInit Lib "DB.dll" (ByRef bTheDSN() As Byte, > ByVal iLevel As Integer)
... As mentioned in another reply, iLevel should actually be a Long, since a VB Integer is 16 bits, and a Win32 int is 32 (so is a Win32 long, actually). To go a little bit in depth about the problem with the first parameter... In C, an array is hardly a type at all (it's just some sugar on top of a pointer). In VB, they definitely are their own type. You have your Declare to actually pass an array, and your C code isn't expecting a VB type array. All it's expecting is the address of the first character of a string. One way to do this would be to pass a single Byte ByRef. Then you'd call it passing the first element of your array (bDSN(0)). But this is probably what you really want. As Tom Shelton mentioned, VB can do conversion from VB's Unicode BSTRs to null-terminated ANSI strings automagically. This leads to the following declaration: Private Declare Sub DbLogInit Lib "DB.dll" (ByVal TheDSN As String, ByVal Level As Long) HTH Murphy www.constantthought.com
|
Mon, 24 Oct 2005 16:32:03 GMT |
|
 |
Craig Power #12 / 22
|
 VB Error: "Bad DLL Calling Convention"
Quote:
> Thanks for the response. Actually, it turns out that I have indirect > control and access to the DLLs under discussion, but the problem is that > these same DLLs are already being used by a BUNCH of VC++ programs. > Even if I could get the functions changed to _stdcall, then it seems > that would break all of the VC++ programs :(.
It shouldn't break the VC programs on a source level, although they would have to be recompiled for the updated signature.
|
Mon, 24 Oct 2005 23:08:53 GMT |
|
 |
Tom Shelto #13 / 22
|
 VB Error: "Bad DLL Calling Convention"
Quote: > VB actually can call cdecl functions natively with no "hacks" required -- > just not if you declare them with the Declare statement. If you define them > in a Type Library (which can be compiled with MKTYPLIB, which is on the VB > CD), and reference the compiled type library in your VB project -- you can > just call them. You should be able to find information about this on the > net, or ask for more help here.
Though, I would personally consider that a bit of a hack (though not as bad as some other's I've seen) - that is a piece of information I did not know. I think I will file that little gem in the must try out bin :) Of course, I will probably never need it for any practicle purpose - since I actually don't do VB anymore (except in maintainence mode). Doing C# now... And this isn't a problem since you can specify the calling convention to use with external calls (same with VB.NET). Tom Shelton
|
Tue, 25 Oct 2005 06:49:51 GMT |
|
 |
Murphy McCaule #14 / 22
|
 VB Error: "Bad DLL Calling Convention"
Come on, Type Libraries are a fundamental part of VB -- it couldn't work without them. How much of a hack could it be? ;) Murphy www.constantthought.com
... Quote: > Though, I would personally consider that a bit of a hack (though not as bad > as some other's I've seen) - that is a piece of information I did not know. > I think I will file that little gem in the must try out bin :) Of course, I > will probably never need it for any practicle purpose - since I actually > don't do VB anymore (except in maintainence mode). Doing C# now... And > this isn't a problem since you can specify the calling convention to use > with external calls (same with VB.NET).
...
|
Tue, 25 Oct 2005 09:27:34 GMT |
|
 |
Tom Shelto #15 / 22
|
 VB Error: "Bad DLL Calling Convention"
Quote: > Come on, Type Libraries are a fundamental part of VB -- it couldn't work > without them. How much of a hack could it be? ;)
I said a bit... Really, it isn't to bad. It's just that many VB programmers go a little cross eyed when you mention IDL, ODL, MKTYPLIB, or MIDL. I do find the idea facinating though... Tom Shelton Quote: > Murphy > www.constantthought.com
> ... > > Though, I would personally consider that a bit of a hack (though not as > bad > > as some other's I've seen) - that is a piece of information I did not > know. > > I think I will file that little gem in the must try out bin :) Of course, > I > > will probably never need it for any practicle purpose - since I actually > > don't do VB anymore (except in maintainence mode). Doing C# now... And > > this isn't a problem since you can specify the calling convention to use > > with external calls (same with VB.NET). > ...
|
Tue, 25 Oct 2005 11:39:48 GMT |
|
|
Page 1 of 2
|
[ 22 post ] |
|
Go to page:
[1]
[2] |
|