hi Pradeepan,

while your suggestion is absolutely useful here, it only applies to vb programmers. Making dlls for a whole range of languages is the aim. Thanks for your suggestions anyway.

the thing behind introducing the mangling here was for the ability to detect the number and size of parameters passed to a function without referring to something. Producing inc files becomes much easier for large dlls then.

So including your tlb into the package, it becomes even more open to languages.

Regards,
Art
Posted on 2003-11-27 11:40:42 by art_sands
OK - there seems to be many opinions on how to call DLLs from VB.

If you use a Windows API call you use the Private Declare function method - and that is the way to call your assy DLL

build your DLL and use a .DEF file to Export (make public) the routines you want to use.

Once the file has been assembled(turned into a DLL) to use the DLL routines, whilst developing your VB program copy the DLL to the windows system folder - otherwise VB won't know where to look for it.

In your VB program declare a function eg:

Private Declare function My_DLL_Routine lib "the name of your dll.DLL" (byval params as long , byval params as long etc etc) as long

Naturally your params may not be a LONG - so put the correct para type in - also you may use byref instead of byval - but becareful with this as it this most common form of mistake which will cause a crash. Remember BYVAL passes the value whereas BYREF pass a pointer to the variable.
Don't forget the AS LONG (etc) after the closing bracket on the list of params - miss it off and you get some strange results.

To call the routine simply type the name of the function eg

My_DLL_Routine param1,param2 etc


And that is all there is to it - there is absolutely no need for all of these unusual and unnecessary routines. Just remember how you call a Windows API call like BitBlt and you can't go wrong.

One more thing if you miss off the byval in the declaration statement 9 times out of 10 the function will still work - however the routine will not work correctly or return incorrect values or quite simply just crash - i've never had it bring up an error of Bad DLL Calling Convention.

A Bad DLL Calling Convention is quite simply corruption of the aforementioned assy registers - remember it is Windows that is flagging the error because the value in the registers are not what it expected to see.
Posted on 2003-11-27 11:49:14 by s1cjet
s1cjet I'm sorry but you are wrong.

I'm having a Bad DLL calling convention right now and I'm preserving all those registers.

"Bad DLL calling convention (Error 49)
See Also Specifics

Arguments passed to a dynamic-link library (DLL) must exactly match those expected by the routine. Calling conventions deal with number, type, and order of arguments. This error has the following causes and solutions:

Your program is calling a routine in a DLL that's being passed the wrong type of arguments.
Make sure all argument types agree with those specified in the declaration of the routine you are calling.

Your program is calling a routine in a DLL that's being passed the wrong number of arguments.
Make sure you are passing the same number of arguments indicated in the declaration of the routine you are calling.

Your program is calling a routine in a DLL, but isn't using the StdCall calling convention.
If the DLL routine expects arguments by value, then make sure ByVal is specified for those arguments in the declaration for the routine.

Your Declare statement for a Windows DLL includes CDecl. "

This is about parameters not registers.

:alright:
Posted on 2003-11-27 12:01:14 by Eternal Idol Birmingham
Hi Idol,

that's really strange - i've just tried producing an error using the method you have explained and it doesn't produce any error !!

I'm using VB6 enterprise edition - i can't really see why the versions of VB would affect it !

Any way - there seems to be a number of attributes to this error code and what will correct them ! In my situation corrupting the ESI EDI EBP or EBX causes the problems.
Posted on 2003-11-27 14:33:35 by s1cjet
so instead of draggin it any further into the gloom of debate let's summarize a few points, whether they apply to the situation or not:

1. Save and restore ESI, EDI, EBX, and EBP. (Never change EBP)
2. Verify number and type of parameters passed to be correct.
3. Export functions with mangled names.
4. Use a .def file to create function labels pointing to equivalent exported functions, thus adding support for languages that may not support name mangling.
5. Add typelibs for easing programming for VHLLS.
6. For calling functions in VC++ (a) add libs and (b) declare prototypes like this

extern "C" int __stdcall MyFunc(void); (check that Mariano).

7. Continue research and debate.

lol
:grin:

Regards,
Art
Posted on 2003-11-27 15:08:43 by art_sands
Well said Art_Sands.
Posted on 2003-11-27 15:11:55 by s1cjet
Yes you are right about this three : ESI EDI and EBX, you should preserve them always.

And of course if you change badly EBP there's a problem with PARAMETERS because EBP is the stack pointer ...

"VB can only handle _stdcall or _fastcall. Both calling conventions mean that the called function cleans up the stack and parameters are passed from right to left.
If you ever run into a ?Bad DLL calling convention? when you call a specific function from VB, it means that this function doesn?t support the stdcall or fastcall calling convention."

http://www.mentalis.org/vbtutor/vcdll1.shtml

Regards.
:alright:
Posted on 2003-11-28 02:23:52 by Eternal Idol Birmingham

i've been writing software for 20 years - started when i was 16 am now 36 and i've been writing commercial software for the UKs oldest and greatest software house all that time - please don't assume you know my lifes history just from one message.

Ok, good for you. That means you are not a newbie, and have even less excuse for getting the solution to this problem wrong.

Originally posted by s1cjet
Once the file has been assembled(turned into a DLL) to use the DLL routines, whilst developing your VB program copy the DLL to the windows system folder - otherwise VB won't know where to look for it.

This is misleading to the point of being incorrect. You can have your assembled dll sitting in the same folder as your VB exe, as Windows checks that location first when looking for a module that needs loading (note that it is Windows that looks, not VB as you mentioned), this location is known as "AppPath", most HLL programmers know of it ;)

You can also:
- add the path to the PATHs environmental variable (either USER or SYSTEM version)
- directly specify the path to the dll in the VB function declare (but this is not an ideal practice)
It is not good practice to just throw all your dlls into the %system32% directory "just so Windows can find them". As a professional developer you will already understand the reasons for that.

Originally posted by s1cjet
Don't forget the AS LONG (etc) after the closing bracket on the list of params - miss it off and you get some strange results.

No you won't. The VB compiler lets you call a function and not assign the return value, it is a feature of VB (ie it allows you to treat a Function as a Sub). You will get a runtime problem though if you declare a non-value-returning API function as a Function, but then attempt to assign the return value to a variable, the compiler will be fine with this but you will get garbage in your variable, because whatever is in eax is the value assigned to the variable.

Originally posted by s1cjet
A Bad DLL Calling Convention is quite simply corruption of the aforementioned assy registers - remember it is Windows that is flagging the error because the value in the registers are not what it expected to see

This is absolutely incorrect. If the registers are not preserved, you will get strange results, and most often a GPF. Windows *does not* flag an error if you don't preserve, Windows does not check for this at all. The error occurs when the calling function tries to execute an operation on, or using the value in, one of the registers that should have been preserved.

Originally posted by s1cjet
before you go around telling people something is wrong please ask a few others - Windows DOES use the following registers ESI EDI EBP EBX - it doesn't matter if you are writing an EXE, DLL, Library , COM, Object or something you would like inserted up your rectum it still uses those registers.
No kidding? You obviously have a reading problem: i *never* said that Windows does not use those registers. *All* OS's use them (especially ebp ;) ) What i said was: the original problem had nothing to do with register preservation, and that out of the *original* list you mentioned only ebx was the mandatory one to preserve, and the rest were just preserved out of politeness to the calling function. There *are* other registers that need to be preserved, but they were not being discussed.

Originally posted by s1cjet
There are plenty of tutorials around which describe fairly well what I - and everyone who wrote the last few messages - already seem to know about this.
Yep, that seems to be the only place you get your knowledge from - other people's tutorials. And "seem to know" is a good phrase, as you have demonstrated that you actually *didn't* know. I think that if you check the following threads:
here,
here,
here,
here,
here,
here,
you will see that i indeed do "seem" to "know about this". Also note the date on those posts (early 2002), and note that this list is not an exhaustive one on my replies to VB->asm topics. Would you like me to write you a tutorial so you can learn a little more? :alright:

Originally posted by s1cjet
I'm starting to wonder if you know what assy or VB is !!!

Umm, yeah, i do, that is what my job is: a senior developer for a very large multinational software company. But this is not a pissing contest, so let's not turn it into one. The reason why i have bothered to answer your posts is because some of your information is wrong, and some of it is misleading. When there are newbies around, they take what you say as gospel, so it is important that it is correct, or at least points them to a source for correct information.


s1cjet,
before you write another inane flame to me, carefully read what has been written, and make sure you fully understand it. Yes i have (sort of) flamed you, but i have also pointed out your errors. Live and learn, and know your HLLs before trying to educate others on how to use a LLL.


everyone else,
if you are still looking for information, check the threads linked to in this post. Like i have said previously, this subject has already been discussed extensively many times before in this forum.



P.S. I will not be answering any more flames in this thread because:
- this forum is not the place for it
- my time is too precious, i have far too many other things to be doing instead
- nobody is really interested in a flame war
Posted on 2003-11-28 20:08:23 by sluggy
Sluggy,
I can't believe you wated your time writing that - talking about reading problems - if you look back over the recent posts you'll find that the preservation of the registers did fix the guys problem - end of story - or did you not read that art_sands said I was correct

:alright:
Posted on 2003-11-28 20:20:33 by s1cjet
jeez sluggy,

i didn't see that comin. well let's say the debate is closed until someone else pops it out once again in some other thread. salad got what he wanted, but left us fighting. sluggy, i would say we've all poured our bits of knowledge into this thread, and everybody who contributed taught something and learnt something. Nobody's perfect.

BTW, the links you've provided are really richie rich. Thanks and take care.

Regards,
Art
Posted on 2003-11-29 02:38:12 by art_sands
another good FAQ contender.
Posted on 2003-12-16 18:59:59 by evil__donkey