Linking against a Win32-DLL

Marc Müller dont at spam.me
Tue Jul 10 07:39:14 PDT 2007


Sorry - there is still a problem...

At first:
I downloaded Code::Blocks and installed the D-Compiler and the 
Ddbg-Debugger.
After downloading - it took me less than 5 minutes to get everything 
working. That's the way it should be ;-)

Now back to the problem:
When using extern(Pascal) the stack seems to be clean.
And the function I used in former news works flawless (because I passed 
three times a zero-value)

Now I tried to call the external functions with real parameters.
Then again some very strange bugs occurred, but thanks to your debugger 
I found the reason quickly:

The program pushes the parameters in reversed order on the stack.
I wrote some lines of inline-assembler to reverse the order manually:


=============================================================
int result = WTInfoA(WTI_DEVICES, i, buffer);
asm
{
     nop;

     push dword ptr buffer;
     push i;
     push WTI_DEVICES;

     call WTInfoA;
     mov result, EAX;
}
-------------------------------------------------------------
Compiles to:
-------------------------------------------------------------
push 0x64
push dword [ebp-0xc]
push dword [ebp-0x10]
call 0x414748	WTINFOA
mov [ebp-0x8], eax

nop
push dword [ebp-0x10]
push dword [ebp-0xc]
push 0x64
call 0x414748	WTINFOA
mov [ebp-0x8], eax
=============================================================

When I use the asm-code the function is called correctly.

Do you know a calling convention or compiler/linker switch to tell D to 
let the callee clean up the stack like in extern(Pascal), but push the 
parameters in reverse order on the stack?

Kind regards,
	-Marc-



Jascha Wetzel schrieb:
> 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