How to painlessly initialize function pointers?

394 views Asked by At

I want to load Win32 API functions using Runtime.loadLibrary and GetProcAddress(...). Using mixin:

template GetProcA(alias func, alias name_in_DLL)
{
    const char[] GetProcA = func ~ ` = cast(typeof(`~func~`)) GetProcAddress(hModule,"`~name_in_DLL~`");`;
}
...
static extern (Windows) Object function (HWND hWnd, int nIndex) GetWindowLong;
static extern (Windows) Object function (HWND hWnd, int nIndex, Object dwNewLong) SetWindowLong;

I can instantiate it (in the class constructor) this way:

mixin GetProcA!("SetWindowLong", "SetWindowLongA");

but if use it again for another function:

mixin GetProcA!("GetWindowLong", "GetWindowLongA");

the compiler complains:

mixin GetProcA!("GetWindowLong","GetWindowLongA") GetProcA isn't a template...

I don't see the point: if the first instantiation created GetProcA and I can't use it again, so how does it help me here ?

2

There are 2 answers

7
kennytm On BEST ANSWER

Judging from your code, you want a mixin expression, not template mixin:

string GetProcA(string func, string name_in_dll)
{
   return func ~ ` = cast(typeof(` ~ func ~ `)) ` ~
                       `GetProcAddress(hModule,"` ~ name_in_dll ~ `");`;
}

mixin(GetProcA("SetWindowLong", "SetWindowLongA"));
mixin(GetProcA("GetWindowLong", "GetWindowLongA"));

Actually, you don't even need a mixin. An inner template function is enough:

hModule = ...;

void GetProcA(T)(ref T func, string name_in_all)
{
    func = cast(typeof(func)) GetProcAddress(hModule, toStringz(name_in_all));
}

GetProcA(SetWindowLong, "SetWindowLongA");
GetProcA(GetWindowLong, "GetWindowLongA");
4
BCS On

I think KennyTM is correct. However for completeness, you can use the same template mixin more than once if you name them. Search for "MixinIdentifier" here.