【发布时间】:2017-07-17 21:16:01
【问题描述】:
我想设置一个全局挂钩,但在从我创建的 dll 中获取挂钩过程的地址时遇到问题。
我在 stackoverflow 上读到该问题可能是由名称修改引起的。为了消除这个问题,你必须用extern "C"将你的导出函数包装在你未来的dll中,我就是这样做的。然而,这并没有帮助。
这是我的程序:
Main.cpp
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
HHOOK hHookKeyboard;
HINSTANCE keyboardProcDLL;
HOOKPROC hookProcKeyboard;
keyboardProcDLL = LoadLibrary(L"C:/PV_KeyboardDLL.dll");
if (keyboardProcDLL == NULL)
{
MessageBox(NULL, L"Could not load library!", L"Error", MB_ICONERROR);
return -1;
}
hookProcKeyboard = (HOOKPROC)GetProcAddress(keyboardProcDLL, "PV_KeyboardProc");
if (hHookKeyboard == NULL)
{
MessageBox(NULL, L"Could not load function from library!", L"Error", MB_ICONERROR);
return -1;
}
hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, hookProcKeyboard, keyboardProcDLL, 0);
while (1)
{
}
return 0;
}
PV_KeyboardDLL.cpp
bool toggleOnOff = false; // off by default
template<typename Type>
inline bool highOrderBit(Type value)
{
return (value & (1 << sizeof(Type) * 8 - 1));
}
template<typename Type>
inline bool lowOrderBit(Type value)
{
return (value & 1);
}
extern "C"
{
__declspec(dllexport) LRESULT CALLBACK PV_KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// process event
if (nCode < 0) // do not process message
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
if (wParam != WM_KEYDOWN)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
KBDLLHOOKSTRUCT* KeyBoardHookStruct = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
DWORD keyCode = KeyBoardHookStruct->vkCode;
bool ctrlDown, altDown;
// high-order is 1 - DOWN
ctrlDown = highOrderBit(GetKeyState(VK_LCONTROL));
altDown = highOrderBit(GetKeyState(VK_MENU));
// ctrl + alt + 1(key down)
if (ctrlDown && altDown && (keyCode == 0x31))
{
// toggle bool
MessageBox(NULL, L"Workin", L"Ok", MB_OK);
toggleOnOff = !toggleOnOff;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
__declspec(dllexport) bool onOrOff()
{
return toggleOnOff;
}
}
我可以加载 dll,但在调用 GetProcAddress() 之后,hookProcKeyboard 是 NULL。
我是 WINAPI 的新手,我有点卡住了,所以非常感谢您的帮助,谢谢。
【问题讨论】:
-
尝试
GetProcAddress(keyboardProcDLL, "_PV_KeyboardProc");或使用nirsoft.net/utils/dll_export_viewer.html 等工具查看DLL 导出(名称) -
"_PV_KeyboardProc@12" 真正导出。需要为此名称调用 GetProcAddress
-
试过
_PV_KeyboardProc和_PV_KeyboardProc@12,还是不行 -
__declspec(dllexport)导出修饰名,不推荐。您应该使用 DEF 文件来导出未修饰的名称。 -
只需在 dll 中搜索
PV_KeyboardProc这个名称 - 在这里查看它的形式。当然最好使用def文件。您甚至可以仅按序数导出它 -PV_KeyboardProc @1 NONAME PRIVATE