Linking against a Win32-DLL

Jascha Wetzel firstname at mainia.de
Mon Jul 9 10:39:54 PDT 2007


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


i used Ddbg to hunt this down in a very short amount of time, btw ;)

Marc Müller wrote:
>> Is it possible you're doing extern(C) when you need to be doing 
>> extern(Window), or vice versa?
>>
>> I don't have much experience with that so I'm just throwing it out. 
>> Maybe it just won't link if you get that wrong.
> 
> With extern(Windows) the program does not link :-(
> 
> I simplified the program and wrote it to
> digitalmars.D.learn ("Problems when using DLL-Functions")
> as Bjoern suggested.
> 
> Again - thanks a lot for your help!
>     -Marc-



More information about the Digitalmars-d mailing list