windows – 有没有办法找到在GetProcAddress中使用的C错位名称?
发布时间:2020-12-14 04:37:50 所属栏目:Windows 来源:网络整理
导读:使用带有C的GetProcAddress的常见“解决方案”是“extern”C“,但是会打破重载.名称修改允许多个函数共存,只要它们的签名不同.但是有没有办法找到这些错位的名称GetProcAddress的? 解决方法 VC编译器知道自己的名称修改方案,为什么不使用它呢?内部模板 typ
使用带有C的GetProcAddress的常见“解决方案”是“extern”C“,但是会打破重载.名称修改允许多个函数共存,只要它们的签名不同.但是有没有办法找到这些错位的名称GetProcAddress的?
解决方法
VC编译器知道自己的名称修改方案,为什么不使用它呢?内部模板< typename T> T GetProcAddress(HMODULE h,const char * name),宏__FUNCDNAME__包含错误的GetProcAddress名称.这包括T部分.因此,在GetProcAddress< void(*)(int)中,我们有一个子字符串,其名称为void(*)(int).从那以后,我们可以简单地得出虚假的名称void foo(int); 此代码依赖于VC宏__FUNCDNAME__.对于MinGW,您需要将其基于__PRETTY_FUNCTION__.
FARPROC GetProcAddress_CppImpl(HMODULE h,const char* name,std::string const& Signature) { // The signature of T appears twice in the signature of T GetProcAddress<T>(HMODULE,const char*) size_t len = Signature.find("@@YA"); std::string templateParam = Signature.substr(0,len); std::string returnType = Signature.substr(len+4); returnType.resize(templateParam.size()); // Strip off our own arguments (HMODULE and const char*) assert(templateParam == returnType); // templateParam and returnType are _pointers_ to functions (P6),so adjust to function type (Y) std::string funName = "?" + std::string(name) + "@@Y" + templateParam.substr(2); return ::GetProcAddress(h,funName.c_str()); } template <typename T> T GetProcAddress(HMODULE h,const char* name) { // Get our own signature. We use `const char* name` to keep it simple. std::string Signature = __FUNCDNAME__ + 18; // Ignore prefix "??$GetProcAddress@" return reinterpret_cast<T>(GetProcAddress_CppImpl(h,name,Signature)); } // Showing the result struct Dummy { }; __declspec(dllexport) void foo( const char* s) { std::cout << s; } __declspec(dllexport) void foo( int i,Dummy ) { std::cout << "Overloaded foo(),got " << i << std::endl; } __declspec(dllexport) void foo( std::string const& s ) { std::cout << "Overloaded foo(),got " << s << std::endl; } __declspec(dllexport) int foo( std::map<std::string,double> volatile& ) { std::cout << "Overloaded foo(),complex typen"; return 42; } int main() { HMODULE h = GetModuleHandleW(0); foo("Hello,"); auto pFoo1 = GetProcAddress<void (*)( const char*)>(h,"foo"); // This templated version of GetProcAddress is typesafe: You can't pass // a float to pFoo1. That is a compile-time error. pFoo1(" worldn"); auto pFoo2 = GetProcAddress<void (*)( int,Dummy )>(h,"foo"); pFoo2(42,Dummy()); // Again,typesafe. auto pFoo3 = GetProcAddress<void (*)( std::string const& )>(h,"foo"); pFoo3("std::string overloadn"); auto pFoo4 = GetProcAddress<int (*)( std::map<std::string,double> volatile& )>(h,"foo"); // pFoo4 != NULL,this overload exists. auto pFoo5 = GetProcAddress<void (*)( float )>(h,"foo"); // pFoo5==NULL - no such overload. } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
- 控制台程序转化为windows服务
- windows – 使用Dos批处理文件重命名多个文件
- 如何将Turbo Pascal for Win32的I / O端口访问转
- 什么是在Windows Server 2003中运行的优秀SSH服务
- windows – 无法启动服务:无法加载程序集
- Windows安全日志
- 使用WPF DataGridHyperLinkColumn项打开Windows资
- iis-7 – PUT和DELETE在Windows 2008 Server IIS
- windows-server-2008-r2 – 针对Windows Server
- windows – 如果我使用LoadIconWithScaleDown创建
热点阅读