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

时间:2012-01-10 15:23:25

标签: d dmd

我想使用Runtime.loadLibraryGetProcAddress(...)加载Win32 API函数。使用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;

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

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

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

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

编译器抱怨:

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

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

2 个答案:

答案 0 :(得分:6)

根据您的代码判断,您需要mixin expression,而不是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"));

实际上,你甚至不需要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");

答案 1 :(得分:3)

我认为KennyTM是正确的。但是,为了完整起见,如果您为其命名,可以多次使用相同的模板 mixin。搜索"MixinIdentifier" here