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