在 C++ 中转换 GetProcAddress 返回的指针
Posted
技术标签:
【中文标题】在 C++ 中转换 GetProcAddress 返回的指针【英文标题】:Casting GetProcAddress returned pointer in C++ 【发布时间】:2014-02-02 22:50:22 【问题描述】:GetProcAddress 返回一个函数指针。 假设我们得到函数 Beep 的地址(它的声明可以在 WinBase.h 中找到(当包括 Windows.h 时))
BOOL WINAPI Beep(
_In_ DWORD dwFreq,
_In_ DWORD dwDuration
);
那么经典代码可能看起来像
typedef BOOL(__stdcall *pbeep)(DWORD , DWORD );
pbeep beep = NULL;
FARPROC fptr = GetProcAddress(Hnd,"Beep");
beep = reinterpret_cast<pbeep>(fptr);
if( beep != NULL )
beep( 440, 1200 ); //this generates a beep for 1.2 secs...
一切看起来都很好并且工作正常。 我的问题:
考虑到编译器可以“以某种方式”从 WinBase.h 中包含的 Beep() 声明中获取函数指针“信息”,有什么方法可以避免 typedef 声明。 我的目标是以某种方式重新使用已经包含在已包含的 .h 文件中的信息(返回/参数/等),其中声明了 Beep() 函数,而不必在 typedef 上手动重复所有这些信息。为一个函数执行此操作时没关系,但是当函数数量增加时,这些 typedef 确实是一种痛苦和错误的一大来源。 可以吗?
编辑; 我很快就会迁移到 VS 2013 但到目前为止仍在使用 VS2008 那么这个想法就是不使用 C++11
【问题讨论】:
一件事——您在 typedef 示例中的返回类型不正确。在 typedef 示例中它应该是 BOOL。 PaulMcKenzie... Nabla 你是对的;代码现已更正 会用延迟加载DLL的工作吗? msdn.microsoft.com/en-us/library/151kt790.aspx 【参考方案1】:您可以在 C++11 中创建一个函数来执行此操作(或者如果您可以让 Boost.Typeof 出价,则可能是 C++03):
template<typename F>
F GetKnownProcAddress(HMODULE hmod, const char *name, F)
auto proc = reinterpret_cast<F>(GetProcAddress(hmod, name));
if (!proc) /*throw or something*/
return proc;
int main()
auto beep = GetKnownProcAddress(Hnd, "Beep", Beep);
如果你愿意使用宏,你可以更进一步:
//where GetKnownProcAddressImpl is the above; also consider the usual STRINGIFY
#define GetKnownProcAddress(hmod, func) GetKnownProcAddressImpl(hmod, #func, func);
auto beep = GetKnownAddressProc(Hnd, Beep);
【讨论】:
【参考方案2】:#include <windows.h>
int main()
decltype(Beep)* beep = (decltype(Beep)*)GetProcAddress(GetModuleHandle("Kernel32.dll"), "Beep");
beep(440, 1200);
【讨论】:
您可以使用auto
使其更简洁。 auto beep = (decltype(Beep)*)GetProcAddress(GetModuleHandle("Kernel32.dll"), "Beep");
【参考方案3】:
在c++11中你可以写
decltype (&Beep) beep_ptr = reinterpret_cast<decltype (&Beep)>GetProcAddress(Hnd,"Beep");
但我不明白你为什么要这样做 - 如果你已经有一个指向函数的指针,为什么要手动加载它?
【讨论】:
我没有指针;指针由 GetProcAddress 返回并且必须被强制转换;我想简化转换,而不必再次手动添加所有信息。我有 .h 声明和返回的 FARPROC 指针;我梦想着把这些部分放在一起,不再输入 typedef ...【参考方案4】:或者试试:-
typedef BOOL (*pbeep)(DWORD, DWORD);
FARPROC fptr = GetProcAddress(Hnd,"Beep");
((pbeep)fptr)( 440, 1200);
【讨论】:
【参考方案5】:BOOL (__stdcall *beep)(DWORD, DWORD); // beep - pointer to function with parameters (DWORD, DWORD) and result of type bool
(FARPROC)beep = GetProcAddress(Hnd,"Beep");
if( beep != NULL )
beep( 440, 1200 ); //this generates a beep for 1.2 secs...
【讨论】:
发布答案时,请添加说明并说明您更改或添加的内容或其工作原理或其他内容。尽管您的答案可能是解决方案,但可能有些阅读此内容的人不理解它的含义或它的工作原理。以上是关于在 C++ 中转换 GetProcAddress 返回的指针的主要内容,如果未能解决你的问题,请参考以下文章
为啥传统的 GetProcAddress 到 std::function 工作不简单
*** 异常发生在 C++ Codegear 而不是 Visual C++