如何轻松初始化函数指针?

Tar*_*Tar 4 d dmd

我想使用Runtime.loadLibrary和加载Win32 API函数GetProcAddress(...).使用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;
Run Code Online (Sandbox Code Playgroud)

我可以通过这种方式实例化它(在类构造函数中):

mixin GetProcA!("SetWindowLong", "SetWindowLongA");
Run Code Online (Sandbox Code Playgroud)

但如果再次使用它为另一个功能:

mixin GetProcA!("GetWindowLong", "GetWindowLongA");
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:

mixin GetProcA!("GetWindowLong","GetWindowLongA") GetProcA isn't a template...
Run Code Online (Sandbox Code Playgroud)

我没有看到这一点:如果创建了第一个实例GetProcA,我又不能再使用它,那么它对我有什么帮助呢?

ken*_*ytm 6

从你的代码来看,你需要一个mixin表达式,而不是模板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"));
Run Code Online (Sandbox Code Playgroud)

实际上,你甚至不需要mixin.内部模板功能就足够了:

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");
Run Code Online (Sandbox Code Playgroud)