Как безболезненно инициализировать указатели функций? - PullRequest
4 голосов
/ 10 января 2012

Я хочу загрузить функции Win32 API, используя Runtime.loadLibrary и 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;

Я могу создать его экземпляр (в конструкторе классов) следующим образом:

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

, но если использовать его снова для другой функции:

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

компилятор жалуется:

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

Я не вижу смысла: если первое создание создало GetProcA, и я не могу использовать его снова, так как это поможет мне здесь?

Ответы [ 2 ]

6 голосов
/ 10 января 2012

Судя по вашему коду, вам нужно выражение mixin , а не 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"));

На самом деле вам даже не нужен миксин.Достаточно внутренней функции шаблона:

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");
3 голосов
/ 10 января 2012

Я думаю KennyTM правильно.Однако для полноты вы можете использовать один и тот же шаблон миксин несколько раз, если назовете их.Ищите "MixinIdentifier" здесь .

...