加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

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.
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读