Thread overview
Problems when using DLL-Functions
Jul 09, 2007
Marc Müller
Jul 09, 2007
torhu
Jul 09, 2007
Marc Müller
Jul 09, 2007
BLS
July 09, 2007
Hello,

I wrote a small program, which is using a function from a Windows system-dll.
So I used the implib-tool to get a corresponding library-file:

implib.exe /s wintab32.lib C:\WINDOWS\system32\Wintab32.dll

I can call functions from the dll correctly and also get the expectet return values. But under some circumstances the application crashes - and I just don't know why...


=========================================================
import std.stdio;
import std.c.windows.windows;

extern(C)
UINT WTInfoA(UINT, UINT, LPVOID);

version = A;

void main(char[][] args)
{
	version (A)
	{
		writefln("Getting WTInfo...");
		WTInfoA(0, 0, null);
		writefln("Received WTInfo");
	}

	version (B)
	{
		writefln("Getting WTInfo...");
		int value = WTInfoA(0, 0, null);
		writefln("Received WTInfo");
	}

	version (C)
	{
		try
		{
			writefln("Getting WTInfo...");
			WTInfoA(0, 0, null);
			writefln("Received WTInfo");
		}
		catch (Exception e)
		{
			writefln("An error has occured:");
			writefln(e.msg);
		}
	}

	version (D)
	{
		if (WTInfoA(0, 0, null)==0)
			writefln("No graphic tablet available");
	}
}
=========================================================


Now the funny part:

As you can see all versions A-D are doing more or less the same.

Version A crashes with the following output:
# Getting WTInfo...
# Received WTInfo
# Error: Access Violation

Version B works fine.
# Getting WTInfo...
# Received WTInfo

Version C (which is identical to version A - just surrounded by a try-catch-block) does neither crash nor it throws an exception.
# Getting WTInfo...
# Received WTInfo

Version D, which also evaluates the return-Value from the function call like version B crashes.
# Error: Access Violation


I think anything is scrambling my stack - but it is absolutely unpredictable when this occurs - and I have no clue what I can do :-(

The errors are reproducable - Version A always crashes while version B never crashes.

Do you have an Idea?

Kind regards,
	-Marc-
July 09, 2007
Marc Müller wrote:
> extern(C)
> UINT WTInfoA(UINT, UINT, LPVOID);

Try extern (Windows) instead of extern (C) here.

> I think anything is scrambling my stack - but it is absolutely unpredictable when this occurs - and I have no clue what I can do :-(
> 
> The errors are reproducable - Version A always crashes while version B never crashes.
> 
> Do you have an Idea?

The stack getting scrambled is a tell-tale sign of using the wrong calling convention.  I can't find WTInfoA on msdn.com, but I'm guessing it's a stdcall function.
July 09, 2007
torhu schrieb:
> Marc Müller wrote:
>> extern(C)
>> UINT WTInfoA(UINT, UINT, LPVOID);
> 
> Try extern (Windows) instead of extern (C) here.

Thanks for the hint. When I try extern(Windows) the Compiler/Linker complains:

Error 42: Symbol Undefined _WTInfoA@12


Listing the content of the lib-file with

libunres.exe -e -p wintab32.lib

results in:
...
_WTInfoA
...

	-Marc-
July 09, 2007
Marc Müller schrieb:
> Hello,
> 
> I wrote a small program, which is using a function from a Windows system-dll.
> So I used the implib-tool to get a corresponding library-file:
> 
> implib.exe /s wintab32.lib C:\WINDOWS\system32\Wintab32.dll
> 
> I can call functions from the dll correctly and also get the expectet return values. But under some circumstances the application crashes - and I just don't know why...
> 
> 
> =========================================================
> import std.stdio;
> import std.c.windows.windows;
> 
> extern(C)
> UINT WTInfoA(UINT, UINT, LPVOID);
> 
> version = A;
> 
> void main(char[][] args)
> {
>     version (A)
>     {
>         writefln("Getting WTInfo...");
>         WTInfoA(0, 0, null);
>         writefln("Received WTInfo");
>     }
> 
>     version (B)
>     {
>         writefln("Getting WTInfo...");
>         int value = WTInfoA(0, 0, null);
>         writefln("Received WTInfo");
>     }
> 
>     version (C)
>     {
>         try
>         {
>             writefln("Getting WTInfo...");
>             WTInfoA(0, 0, null);
>             writefln("Received WTInfo");
>         }
>         catch (Exception e)
>         {
>             writefln("An error has occured:");
>             writefln(e.msg);
>         }
>     }
> 
>     version (D)
>     {
>         if (WTInfoA(0, 0, null)==0)
>             writefln("No graphic tablet available");
>     }
> }
> =========================================================
> 
> 
> Now the funny part:
> 
> As you can see all versions A-D are doing more or less the same.
> 
> Version A crashes with the following output:
> # Getting WTInfo...
> # Received WTInfo
> # Error: Access Violation
> 
> Version B works fine.
> # Getting WTInfo...
> # Received WTInfo
> 
> Version C (which is identical to version A - just surrounded by a try-catch-block) does neither crash nor it throws an exception.
> # Getting WTInfo...
> # Received WTInfo
> 
> Version D, which also evaluates the return-Value from the function call like version B crashes.
> # Error: Access Violation
> 
> 
> I think anything is scrambling my stack - but it is absolutely unpredictable when this occurs - and I have no clue what I can do :-(
> 
> The errors are reproducable - Version A always crashes while version B never crashes.
> 
> Do you have an Idea?
> 
> Kind regards,
>     -Marc-

Ahem,
If not allready done; Have a look t the D Forum , it seems that our D - Debugger developer -Jascha Wetzel- found a solution.
Bjoern
That s about suggestion something :-(