Page 1 of 1

Bad DLL Calling Convention

Posted: Tue Mar 09, 2004 10:34 am
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!

Re:Bad DLL Calling Convention

Posted: Tue Mar 09, 2004 10:40 am
by Xqzzy Rcxmcq
Does this problem have anything to do with function callback?

Re:Bad DLL Calling Convention

Posted: Tue Mar 09, 2004 2:17 pm
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. ^^

Re:Bad DLL Calling Convention

Posted: Tue Mar 09, 2004 4:54 pm
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.

Re:Bad DLL Calling Convention

Posted: Tue Mar 09, 2004 7:00 pm
by Xqzzy Rcxmcq
Thanks, Tim. And, Nychold.

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

Re:Bad DLL Calling Convention

Posted: Wed Mar 10, 2004 12:51 pm
by Tim
The usual way. In your VB prototype, add As type to the end of the declaration, where type is the return type.

Re:Bad DLL Calling Convention

Posted: Wed Mar 10, 2004 2:40 pm
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?

Re:Bad DLL Calling Convention

Posted: Wed Mar 10, 2004 4:01 pm
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.

Re:Bad DLL Calling Convention

Posted: Wed Mar 10, 2004 11:16 pm
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.

Re:Bad DLL Calling Convention

Posted: Thu Mar 11, 2004 6:51 am
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!

Re:Bad DLL Calling Convention

Posted: Wed May 12, 2004 5:04 pm
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...