tags:

views:

188

answers:

1

I'm accessing a DLL through :

int (__stdcall *Send) (char *);
Send = (int (__stdcall *)(char *)) GetProcAddress(hmModule,"Send");

The original call uses:

int (FAR PASCAL *Send) (char FAR *);
Send = (int (FAR PASCAL *)(char FAR *))GetProcAddress(hmModule,"Send");

Is there any downside to replace FAR by nothing and PASCAL by __stdcall

+2  A: 

Removing FAR may constrain all the modules that to be within the same segment. This is probably fine if this is a small program.
Edit: FAR is however a relic from the past and doesn't apply to win32 targets, and is safe to remove in most cases.

Changing the calling convention, only affects possible inter-op with external modules calling these methods. (it may also have minimal effects on performance, though I'm not even sure of that).

Edit: BUT WOW...! No! can't be done, I didn't notice this was for a WinAPI method, i.e. one when the calling convention has readily be defined for you... and the same probably goes for FAR, it is likely needed.

Next day edit, with hya, the OP's additional details
The target function is defined in windef.h as

extern "C" int APIENTRY Send (LPCSTR sCmd)

With its support for very many OSes, Compiler Versions and locally defined values, windef.h is [fairly enough] a combinatory logic exercise. With most [non MAC] paths, and assuming windef.h is relatively unchanged in this area, APIENTRY boils down to

...
#define APIENTRY  WINAPI
...
#define WINAPI   __stdcall

And since for the same paths, PASCAL also produces __stdcall the first "mystery" is solved, in this particular context (i.e. generally non MAC, MSC compiler 8.0 or above (or a compiler defining _STDCALL_SUPPORTED ...)

With regards to FAR or nothing, it is less clear (to me), but too, most paths in the windef.h macros lead to these two macros as producing nothing. I think it is because the compiler would use the target memory model to figure out what was short and long pointers. At any rate, the target prototype uses LPCSTR, i.e. a "far/long" pointer and this is probably what the compiler produced. Similarly for the FAR modifier used with the function itself, this too unnecessary, with the compiler stubbing for a far call as per the memory model and/or implicitly.

So, the above explains why, YES, the changes made from PASCAL to __stdcall and from FAR to nothing are OK and should result in a functional binary. (probably to be re-checked etc, if you change compiler and/or target OS).

Thank you for this question, as this prompted me to revisit issues I hadn't seen in a while.

mjv
Changing from PASCAL to StdCall will have no performance detriment, as if the DLL was compiled to allow StdCall (which most are) then there would be no difference in access. Hopefully he understands that FAR refers to an address located in a different segment from the defined pointers origination.
Reallyethical
@Reallyethical, right, thanks for confirming the no performance difference, and all OK on FAR. I'm a bit puzzled as to the OP's exact needs etc. You are right most APIs use __stdcall (aka WINAPI), but the implication I get from the question is that this currently works, so switching the calling conv. would definitively break things... Maybe I'm missing some'
mjv
This afternoon when I got the DLL, I looked for a working example and found one in C with the old FAR PASCAL call. I suspect the code was written for a previous version of the DLL. I've just looked at the source and APIENTRY (=>WINAPI =>__stdcall) is used:extern "C"int APIENTRY Send (LPCSTR sCmd)In WinDef.h PASCAL is defined as __stdcall, so it explains why the two work (?).
anno
@hya See my edits, with your added details it now makes sense that, given your overall context (compiler / OS / memory model...) the two versions would produce the same exact same binary with regards to calls to this windows function, and hence they both work. Regards,
mjv
"Removing `FAR` may constrain all the modules that to be within the same segment" ?? Sure, in Win16, but really, it's the 2st century now, and the question IS tagged Win32. Since there's only one code segment anyway, you are constrained to that whether you use `FAR` or not.
MSalters
Right on, @MSalters. my rush to respond and also my rustiness w/ re. to memory models is to blame. Indeed I had not even noted that this was a WINAPI call in my very first response.
mjv