我有这段代码:
int main(int argc, char *argv[])
{
typedef HHOOK(__stdcall *f_funci)(int, HOOKPROC, HINSTANCE, DWORD);
HINSTANCE hGetProcIDDLL = LoadLibrary(L"User32.dll");
if (!hGetProcIDDLL) {
printf("could not load the dynamic library");
printf("%d", GetLastError());
return EXIT_FAILURE;
}
// resolve function address here
f_funci SetWindowsHookEx2 = (f_funci)GetProcAddress(hGetProcIDDLL, "SetWindowsHookExW");
if (!SetWindowsHookEx2) {
printf("could not locate the function SetWindowsHookExW");
printf("%d", GetLastError());
return EXIT_FAILURE;
}
hMouseHook = SetWindowsHookEx2(WH_MOUSE_LL, my_function, hInstance, NULL);
return 0;
}
如何在函数中插入所有这些代码,只需从main调用它来获取SetWindoesHookEx2
并稍后再使用它?
这里的问题是返回的值是typedef HHOOK(__stdcall *f_funci)(int, HOOKPROC, HINSTANCE, DWORD)
,它是HHOOK
结构,我不知道如何处理。
在简历中我想要一些像:
int main(void) {
SetWindowsHook2 = dynamyc_function("User32.dll", "SetWindowsHookExW", int, HOOKPROC, HINSTANCE, DWORD)
hMouseHook = SetWindowsHookEx2(WH_MOUSE_LL, my_function, hInstance, NULL);
return 0;
}
我不能这样做:
HHOOK load_hook(){
typedef HHOOK(__stdcall *f_funci)(int, HOOKPROC, HINSTANCE, DWORD);
HINSTANCE hGetProcIDDLL = LoadLibrary(L"User32.dll");
if (!hGetProcIDDLL) {
printf("could not load the dynamic library");
printf("%d", GetLastError());
return EXIT_FAILURE;
}
// resolve function address here
f_funci SetWindowsHookEx2 = (f_funci)GetProcAddress(hGetProcIDDLL, "SetWindowsHookExW");
if (!SetWindowsHookEx2) {
printf("could not locate the function SetWindowsHookExW");
printf("%d", GetLastError());
return EXIT_FAILURE;
}
return SetWindowsHookEx2;
}
有两个错误:'return' : cannot convert from 'int' to 'HHOOK'
和'return' : cannot convert from 'f_funci' to 'HHOOK'
第一个引用return EXIT_FAILURE;
,第二个引用'返回SetWindowsHookEx2;'
谢谢。
答案 0 :(得分:2)
尝试这样的事情:
#include <map>
#include <string>
std::map<std::wstring, HINSTANCE> libs;
template<typename T>
bool dynamyc_function(LPCWSTR libname, LPCSTR funcname, T *func)
{
HINSTANCE hlib = libs[libname];
if (!hlib)
{
hlib = LoadLibraryW(libname);
if (!hlib)
{
wprintf(L"could not load the dynamic library %s! %d", libname, GetLastError());
return false;
}
libs[libname] = hlib;
}
*func = (T) GetProcAddress(hlib, funcname);
if (!*func)
{
printf("could not locate the function %s! %d", name, GetLastError());
return false;
}
return true;
}
int main(int argc, char *argv[])
{
typedef HHOOK(__stdcall *f_funci)(int, HOOKPROC, HINSTANCE, DWORD);
// resolve function address here
f_funci SetWindowsHookEx2;
if (!dynamyc_function(L"User32.dll", "SetWindowsHookExW", &SetWindowsHookEx2))
return EXIT_FAILURE;
HHOOK hMouseHook = SetWindowsHookEx2(WH_MOUSE_LL, my_function, hInstance, NULL);
if (!hMouseHook)
{
printf("could not set hook! %d", GetLastError());
return EXIT_FAILURE;
}
...
UnhookWindowsHookEx(hMouseHook);
return 0;
}
或者,如果您只对特定功能感兴趣,可以尝试这样的事情:
typedef HHOOK(__stdcall *f_funci)(int, HOOKPROC, HINSTANCE, DWORD);
HHOOK __stdcall Impl_SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
HHOOK __stdcall Stub_SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
f_funci lpSetWindowsHookExW = &Stub_SetWindowsHookExW;
HHOOK __stdcall Impl_SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
}
HINSTANCE hUser32 = NULL;
HHOOK __stdcall Stub_SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
{
if (!hUser32)
{
hUser32 = LoadLibraryW("User32.dll");
if (!hUser32)
{
DWORD err = GetLastError();
printf("could not load the dynamic library! %d", err);
SetLastError(err);
return NULL;
}
}
f_funci func = (f_funci) GetProcAddress(hUser32, "SetWindowsHookExW");
if (!func)
{
DWORD err = GetLastError();
printf("could not locate the function! %d", err);
SetLastError(err);
func = &Impl_SetWindowsHookExW;
}
lpSetWindowsHookExW = func;
return func(idHook, lpfn, hMod, dwThreadId);
}
int main(int argc, char *argv[])
{
HHOOK hMouseHook = lpSetWindowsHookExW(WH_MOUSE_LL, my_function, hInstance, NULL);
if (!hMouseHook)
{
printf("could not set hook! %d", GetLastError());
return EXIT_FAILURE;
}
...
UnhookWindowsHookEx(hMouseHook);
return 0;
}
答案 1 :(得分:1)
您不能在C或C ++中将类型作为运行时参数传递。
在C ++中,您可以使用支持类型参数的模板。类似的东西:
auto SetWindowsHook2 = dynamic_function<HHOOK(__stdcall *)(int, HOOKPROC, HINSTANCE, DWORD)>(L"User32.dll", "SetWindowsHookExW");
其中函数定义为:
template<typename FuncPtr>
FuncPtr dynamic_function(const wchar_t* dllname, const char* fn)
{
HINSTANCE hDLL = LoadLibraryW(dllname);
if (!hDLL) {
printf("could not load the dynamic library");
printf("%d", GetLastError());
return nullptr;
}
// resolve function address here
auto pf = (FuncPtr)GetProcAddress(hDLL, fn);
if (!pf) {
printf("could not locate the function %s", fn);
printf("%d", GetLastError());
return nullptr;
}
return pf;
}
请注意,这个泄漏库引用计数,所以它确实不是一个好的解决方案。更好的方法是为DLL提供一个RAII类,在其析构函数中释放引用(使用FreeLibrary
)。 dynamic_function
可以是DLL-referent对象的成员函数。然后,只要您需要从中获得的函数指针,您就有责任保持该对象的存活。