www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Trouble with DLL address

reply "dnewbie" <run3 myopera.com> writes:
I have a DLL which exports a function GetFunction. GetFunction 
returns a pointer to RealFunction. Now I want to run RealFunction 
from my D program, but for some reason I get the wrong address. 
Here is the code.

---- dll64.c -----
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int __stdcall RealFunction(int a)
{
     return a + 1;
}

typedef int (__stdcall *FuncPtr)(int);

FuncPtr __stdcall GetFunction()
{
     return &RealFunction;
}

---- mydll64.def ----
LIBRARY mydll64.dll
EXPORTS
GetFunction
---------------------

build with MSVC64:
cl -c dll64.c -Fomydll64.obj
link /DLL /OUT:mydll64.dll mydll64.obj /DEF:mydll64.def

And this is the D program.

---- testdll64d.d ----
// dmd -m64 -c testdll64d.d -oftestdll64d.obj
// link /OUT:testdll64d.exe testdll64d.obj

import core.runtime;
import std.c.windows.windows;
import std.stdio;

alias extern(Windows) int function(int) FuncPtr;

int main(string[] args)
{
     HMODULE dll          = LoadLibraryA("mydll64.DLL");
     FARPROC getFunction  = GetProcAddress(dll, "GetFunction");
     FuncPtr realFunction = cast(FuncPtr) getFunction();

     writefln("dll address:          %08x", dll);
     writefln("GetFunction address:  %08x", getFunction);
     writefln("RealFunction address: %08x", realFunction);
     writefln("RealFunction result:  %d",   realFunction(7));//<-- 
CRASH

     return 0;
}
----------------------

Output:
dll address:          180000000
GetFunction address:  180001020
RealFunction address: ffffffff80001000
<CRASH>

BTW, this works:
FuncPtr realFunction = cast(FuncPtr) (getFunction() & 
0x00000000ffffffff | cast(size_t) dll);
Jan 14 2013
next sibling parent reply dennis luehring <dl.soluz gmx.net> writes:
http://dlang.org/type.html

int => signed 32 bits

but don't you need long in D

Am 14.01.2013 10:13, schrieb dnewbie:
 I have a DLL which exports a function GetFunction. GetFunction
 returns a pointer to RealFunction. Now I want to run RealFunction
 from my D program, but for some reason I get the wrong address.
 Here is the code.

 ---- dll64.c -----
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>

 int __stdcall RealFunction(int a)
 {
       return a + 1;
 }

 typedef int (__stdcall *FuncPtr)(int);

 FuncPtr __stdcall GetFunction()
 {
       return &RealFunction;
 }

 ---- mydll64.def ----
 LIBRARY mydll64.dll
 EXPORTS
 GetFunction
 ---------------------

 build with MSVC64:
 cl -c dll64.c -Fomydll64.obj
 link /DLL /OUT:mydll64.dll mydll64.obj /DEF:mydll64.def

 And this is the D program.

 ---- testdll64d.d ----
 // dmd -m64 -c testdll64d.d -oftestdll64d.obj
 // link /OUT:testdll64d.exe testdll64d.obj

 import core.runtime;
 import std.c.windows.windows;
 import std.stdio;

 alias extern(Windows) int function(int) FuncPtr;

 int main(string[] args)
 {
       HMODULE dll          = LoadLibraryA("mydll64.DLL");
       FARPROC getFunction  = GetProcAddress(dll, "GetFunction");
       FuncPtr realFunction = cast(FuncPtr) getFunction();

       writefln("dll address:          %08x", dll);
       writefln("GetFunction address:  %08x", getFunction);
       writefln("RealFunction address: %08x", realFunction);
       writefln("RealFunction result:  %d",   realFunction(7));//<--
 CRASH

       return 0;
 }
 ----------------------

 Output:
 dll address:          180000000
 GetFunction address:  180001020
 RealFunction address: ffffffff80001000
 <CRASH>

 BTW, this works:
 FuncPtr realFunction = cast(FuncPtr) (getFunction() &
 0x00000000ffffffff | cast(size_t) dll);
Jan 14 2013
parent dennis luehring <dl.soluz gmx.net> writes:
Just ignore my post - too early in the morning :(

Am 14.01.2013 10:19, schrieb dennis luehring:
 http://dlang.org/type.html

 int => signed 32 bits

 but don't you need long in D

 Am 14.01.2013 10:13, schrieb dnewbie:
 I have a DLL which exports a function GetFunction. GetFunction
 returns a pointer to RealFunction. Now I want to run RealFunction
 from my D program, but for some reason I get the wrong address.
 Here is the code.

 ---- dll64.c -----
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>

 int __stdcall RealFunction(int a)
 {
       return a + 1;
 }

 typedef int (__stdcall *FuncPtr)(int);

 FuncPtr __stdcall GetFunction()
 {
       return &RealFunction;
 }

 ---- mydll64.def ----
 LIBRARY mydll64.dll
 EXPORTS
 GetFunction
 ---------------------

 build with MSVC64:
 cl -c dll64.c -Fomydll64.obj
 link /DLL /OUT:mydll64.dll mydll64.obj /DEF:mydll64.def

 And this is the D program.

 ---- testdll64d.d ----
 // dmd -m64 -c testdll64d.d -oftestdll64d.obj
 // link /OUT:testdll64d.exe testdll64d.obj

 import core.runtime;
 import std.c.windows.windows;
 import std.stdio;

 alias extern(Windows) int function(int) FuncPtr;

 int main(string[] args)
 {
       HMODULE dll          = LoadLibraryA("mydll64.DLL");
       FARPROC getFunction  = GetProcAddress(dll, "GetFunction");
       FuncPtr realFunction = cast(FuncPtr) getFunction();

       writefln("dll address:          %08x", dll);
       writefln("GetFunction address:  %08x", getFunction);
       writefln("RealFunction address: %08x", realFunction);
       writefln("RealFunction result:  %d",   realFunction(7));//<--
 CRASH

       return 0;
 }
 ----------------------

 Output:
 dll address:          180000000
 GetFunction address:  180001020
 RealFunction address: ffffffff80001000
 <CRASH>

 BTW, this works:
 FuncPtr realFunction = cast(FuncPtr) (getFunction() &
 0x00000000ffffffff | cast(size_t) dll);
Jan 14 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/14/13, dnewbie <run3 myopera.com> wrote:
      FuncPtr realFunction = cast(FuncPtr) getFunction();
Make that: FuncPtr realFunction = cast(FuncPtr) getFunction; Don't call the FARPROC, just cast it.
Jan 14 2013
prev sibling parent "dnewbie" <run3 myopera.com> writes:
The problem is FARPROC. Thank you everybody.

Solution:
import core.runtime;
import std.c.windows.windows;
import std.stdio;

alias extern(Windows) int function(int) FuncPtr;
alias extern(Windows) FuncPtr function() GetFuncPtr;

int main(string[] args)
{
	HMODULE dll            = LoadLibraryA("mydll64.DLL");
	GetFuncPtr getFunction = cast(GetFuncPtr) GetProcAddress(dll, 
"GetFunction");	
	FuncPtr realFunction   = cast(FuncPtr) getFunction();
	
	writefln("dll address:          %08x", dll);
	writefln("GetFunction address:  %08x", getFunction);
	writefln("RealFunction address: %08x", realFunction);
	writefln("RealFunction result:  %d",   realFunction(7));

     return 0;	
}
Jan 14 2013