Bad DLL Calling Convention

Programming, for all ages and all languages.
Post Reply
Xqzzy Rcxmcq

Bad DLL Calling Convention

Post by Xqzzy Rcxmcq »

I created a DLL, using Bloodshed's Dev C++.

It added standard DLL Class Libraries for me, and so I just created a test procedure.

Code: Select all

void LookFnctn (int fnfg) 
{
fnfg = fnfg + 1; 
//This is just a test DLL.
}
And then, in Visual Basic 6, I did a DECLARE.

Code: Select all

Private Declare Function LookFnctn "mydll.dll" (ByVal fnfg as Integer)
In my Command1_Click event, I put:

Code: Select all

Call LookFnctn (13) 
//Or some other number as an argument.
When I start the app, and click Command1, I get "Bad DLL Calling Convention. I supplied an integer argument, so what is the problem? Any help would be appreciated. Thanks!
Xqzzy Rcxmcq

Re:Bad DLL Calling Convention

Post by Xqzzy Rcxmcq »

Does this problem have anything to do with function callback?
Nychold

Re:Bad DLL Calling Convention

Post by Nychold »

It might be that you're declaring it a Function (which must return something) rather than a procedure. Try replacing Function with Procedure and see if that helps.

If not, it might also be a C convention of prepending underscores to its functions. I'm not sure how to fix that in VB, so refer to your documentation or to a better VB programmer (for me, it's been at least 6 years. XD)

EDIT: I seem to recall something about CDECL in Quick Basic...probably still exists in VB. ^^
Tim

Re:Bad DLL Calling Convention

Post by Tim »

Two things:

1. I believe VB uses __stdcall, so declare your function as void __stdcall LookFnctn. This should be the cause of the error.

2. Integer in VB (before .NET) is 16 bits, whereas int in gcc is 32 bits. Either use Long in VB, or short in C.
Xqzzy Rcxmcq

Re:Bad DLL Calling Convention

Post by Xqzzy Rcxmcq »

Thanks, Tim. And, Nychold.

It seems to work well, but, what if I wanted to return something from a function?
Tim

Re:Bad DLL Calling Convention

Post by Tim »

The usual way. In your VB prototype, add As type to the end of the declaration, where type is the return type.
Schol-R-LEA

Re:Bad DLL Calling Convention

Post by Schol-R-LEA »

Just to makes sure I understand this: I would asume you still need the __stdcall modifier (which forces it to use the Pascal calling convetions instead of the C convention) in the C function, and would have to make sure that the VB function type matches the C return type. Thus, a function with the C prototype

Code: Select all

__stdcall int ReturnSomething(int n);
would be declared in VB 6.0 as

Code: Select all

Declare Function ReturnSomething "mydll.dll" (ByVal n as Long) as Long
or in VB.NET as

Code: Select all

Declare Function ReturnSomething "mydll.dll" (ByVal n as Integer) as Integer
Would that be right, Tim?
Tim

Re:Bad DLL Calling Convention

Post by Tim »

Mostly, yes, though stdcall is a calling convention in its own right (Pascal was Win16 -- stdcall is the same as cdecl except that the called function clears the stack). And I believe the calling convention comes after the return type and before the function name, so:

Code: Select all

int __stdcall ReturnSomething(int n)
{ return something; }
<deep breath> Also, changing the calling convention changes the name decoration. Under cdecl, that function would be _ReturnSomething. Under stdcall, it's _ReturnSomething@4 (four because that's the size of the parameter list). Maybe this doesn't apply to gcc, but if you used __declspec(dllexport) to export this function, it would be called _ReturnSomething@4 in the DLL -- not what you want. So to resolve that you'd put together a .DEF file containing the name(s) of the function(s) you wanted exported, such as:

Code: Select all

NAME something.dll
EXPORTS
    ReturnSomething
    ReturnSomethingElse
Regarding the VB code, I don't know what the syntax under VB.NET (aka Visual Fred) would be. It's likely to be completely different from the VB6 equivalent.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Bad DLL Calling Convention

Post by Candy »

Tim Robinson wrote: Mostly, yes, though stdcall is a calling convention in its own right (Pascal was Win16 -- stdcall is the same as cdecl except that the called function clears the stack).
Afaik, not entirely true. In c all parameters are pushed in 'reverse' order, and in __stdcall they're pushed in 'forward' order. __stdcall doesn't allow variable length parameter lists because of that.
Xqzzy Rcxmcq

Re:Bad DLL Calling Convention

Post by Xqzzy Rcxmcq »

Thanks, all.

Now, when I try to use it, it spits out "Cannot find procedure XXX in srvc.dll". Figures ::)

Well, now what?

Thanks in advance!
JustMe

Re:Bad DLL Calling Convention

Post by JustMe »

Xqzzy Rcxmcq wrote: Thanks, all.

Now, when I try to use it, it spits out "Cannot find procedure XXX in srvc.dll". Figures ::)

Well, now what?

Thanks in advance!

Your name is likely mangled. C++ changes the signature of a function in order to allow overloading. You can run dumpbin on your .dll to get the mangled names. Usually you can guess the mangled name of the function by appending a _ to the front and an @ plus 4 times the number of parameters passed along. So something like

extern "C" int __declspec(dllexport) _stdcall Allocate(void);

becomes _Allocate@0

so in VB you would have something like

Private Declare Function Allocate Lib "my.dll" alias "_Allocate@0"() as Long

notice the differences between the two i.e. int in C++ long in VB. Watch out for this kind of thing as it will bite you. Boolean in VB!=bool in C++ ect...
Post Reply