How to call Windows function pointers?
Benji Smith
dlanguage at benjismith.net
Sat Aug 16 10:59:42 PDT 2008
I'm using tango.sys.SharedLib to dynamically load a DLL and get a
function pointer to a win32 API function. And that's working nicely. But
the function pointer is returned as a void*, and to call it, I think I
need to cast it to a function pointer. But the function needs to be
called with extern(Windows) calling conventions. At first, I tried this:
alias uint BOOL;
alias uint DWORD;
alias ulong DWORDLONG;
struct MEMORYSTATUSEX {
DWORD dwLength;
DWORD dwMemoryLoad;
DWORDLONG ullTotalPhys;
DWORDLONG ullAvailPhys;
DWORDLONG ullTotalPageFile;
DWORDLONG ullAvailPageFile;
DWORDLONG ullTotalVirtual;
DWORDLONG ullAvailVirtual;
DWORDLONG ullAvailExtendedVirtual;
}
public void callWin32Function() {
auto lib = SharedLib.load(`c:\windows\system32\kernel32.dll`);
void* sym = lib.getSymbol("GlobalMemoryStatusEx");
auto fn = cast(extern(Windows) BOOL function(MEMORYSTATUSEX)) sym;
MEMORYSTATUSEX memStatus;
fn(memStatus);
}
But the compiler rejects that cast because of the "extern(Windows)" bit.
Without the cast, it compiles, but throws an Access Violation when I
call the function pointer, obviously because it's using the wrong
calling convention.
I hate to suggest that the calling convention should be part of the type
system (because the type system is already burdened with too much,
especially in D2, with const semantics and now thread-sharing
semantics). But clearly two function pointers with different calling
conventions are different types of functions, and it seems like the type
system should take responsibility for ensuring the correct calling
convention.
I've also tried this, thinking that declaring "fn" as a member with the
"extern(Windows)" calling convention would solve the problem:
alias uint BOOL;
alias uint DWORD;
alias ulong DWORDLONG;
struct MEMORYSTATUSEX {
DWORD dwLength;
DWORD dwMemoryLoad;
DWORDLONG ullTotalPhys;
DWORDLONG ullAvailPhys;
DWORDLONG ullTotalPageFile;
DWORDLONG ullAvailPageFile;
DWORDLONG ullTotalVirtual;
DWORDLONG ullAvailVirtual;
DWORDLONG ullAvailExtendedVirtual;
}
extern(Windows) BOOL function(MEMORYSTATUSEX) fn;
public void callWin32Function() {
auto lib = SharedLib.load(`c:\windows\system32\kernel32.dll`);
void* sym = lib.getSymbol("GlobalMemoryStatusEx");
fn = cast(BOOL function(MEMORYSTATUSEX)) sym;
MEMORYSTATUSEX memStatus;
fn(memStatus);
}
But the the compiler still doesn't like that cast. It gives this error:
cannot implicitly convert expression (cast(uint
function(MEMORYSTATUSEX))exFunctionPtr) of type uint
function(MEMORYSTATUSEX) to uintWindows function(MEMORYSTATUSEX)
Anyone have any suggestions?
Thanks!
--benji
More information about the Digitalmars-d-learn
mailing list