Linking against a Win32-DLL

Bill Baxter dnewsgroup at billbaxter.com
Mon Jul 9 14:34:20 PDT 2007


Jascha Wetzel wrote:
> the problem is indeed the calling convention.
> 
> the version of wintab32.dll i found uses FAR PASCAL. the callee's clean 
> up the stack. if you use extern(C), the caller cleans up the stack. 
> therefore the return address at the end of the main function is 
> incorrect and it crashes.
> this is only the case, though, as long as you don't use any local 
> variables. in this case, D uses the ENTER and LEAVE x86 instructions to 
> create and destroy stack frames. the correct stack pointers (the pointer 
> to the former stack frame) are saved (in EBP) and therefore the 
> incorrect value in ESP (that results from the obsolete cleanup) gets 
> overwritten by the saved value, the correct return address is in place 
> -> no crash.
> 
> after looking at the C headers for wintab32.dll, you see that they use 
> the WINAPI = __stdcall = extern(Windows) calling convention only if the 
> win32 headers have been included (WINAPI is defined). else they use FAR 
> PASCAL. since the function names in wintab32.dll do not adhere to the 
> __stdcall convention (leading _ and trailing @X with X being the number 
> of parameter bytes), they must be using FAR PASCAL.
> 
> DMD's extern(Pascal) calling convention expects all uppercase function 
> names. therefore you'll have to specify the /IGNORECASE option to 
> optlink. not that FAR PASCAL has to leading underscore in the function 
> names (as opposed to __cdecl or extern(C)).
> 
> putting it all together:
> - use implib without the /s switch (no leading underscores)
> implib wintab32.lib \WINDOWS\system32\Wintab32.dll
> 
> - declare all imports as extern(Pascal)
> extern(Pascal) UINT WTInfoA(UINT, UINT, LPVOID);
> 
> - pass /IGNORECASE to optlink to compensate for case sensitivity in 
> wintab32.dll
> dmd wintab32.lib wintabtest.d -L/IGNORECASE

But using /IGNORECASE means you can no longer have any functions in your 
app anywhere that are different only in case?

I guess it's not that huge a problem with name mangling.  If you have 
CoolThing and coolthing they're not likely to both be functions... but 
still.

Expecting extern(Pascal) to be all uppercase seems like a bug if that's 
not really how extern(Pascal) libraries do things in practice.

--bb



More information about the Digitalmars-d mailing list