创建博客 登录  
 加关注
   显示下一条  |  关闭

(((silence)))

#define if(...) if(!(__VA_ARGS__))

 
 
 

日志

 
 

DLL,应该有更优雅的玩法  

2008-11-15 14:47:24|  分类: 编程 |  标签: |字号 订阅

隐式调用嘛,链接麻烦;显式调用嘛,代码敲着累,怎么搞才好玩呢?
首先,让我们大胆构想一下,有没有可能做到这样:

dll user32("user32.dll");
user32.call("MessageBoxA", 0 , "Hello, World" , "Look at me!" , 0 );
——当然,还有返回值来着,那就这样吧:
user32.call<int>("MessageBoxA", 0 , "Hello, World" , "Look at me!" , 0 );
这样如何呢,应该还算好用吧~

至于实现——当然是有办法的。

懒得多说,直接给出我的实现吧。

class dll
{
public:
    class module_not_found_exception:
        public std::exception
    { ... };//略

    class function_not_found_exception:
        public std::exception
    { ... };//略
protected:
    std::string  module_name;
    HINSTANCE    hmodule;
    bool         loaded;
public:
    dll(std::string const& path):
        module_name(path),
        hmodule(LoadLibrary(path.c_str())),
        loaded(true)
    {
        if(!hmodule||hmodule==INVALID_HANDLE_VALUE)
            throw(module_not_found_exception(path));
    }
    dll(std::string const& path, HANDLE h, DWORD d):
        module_name(path),
        hmodule(LoadLibraryEx(path.c_str(),h,d)),
        loaded(true)
    {
        if(!hmodule||hmodule==INVALID_HANDLE_VALUE)
            throw(module_not_found_exception(path));
    }
    dll(dll const& another):
        module_name(another.module_name),
        hmodule(another.hmodule),
        loaded(false)
    { }
    dll& operator=(dll const& another)
    {
        FreeLibrary(hmodule);
        loaded=false;
        this->module_name=another.module_name;
        this->hmodule=another.hmodule;
        return * this;
    }
    virtual ~dll()
    {
        if(loaded)
            FreeLibrary(hmodule);
    }
public:
    template < class R >
    R call ( char const * const name ){
        typedef R (*fp)();
        fp fun=reinterpret_cast<fp>(GetProcAddress(hmodule,name));
        if (!fun) throw(function_not_found_exception(name));
        return fun();
    }
// 以这一段为例,注释一下吧,虽然聪明的你肯定看得懂
    template < class R, class A0 >
    R call ( char const * const name, A0 arg0 ) {
        typedef R (*fp)(A0); //fp:函数指针的类型
        fp fun=reinterpret_cast<fp>(GetProcAddress(hmodule,name)); //标准的获取函数地址的方法。有特殊要求——比如认为某些函数可能被HOOK掉了但又不希望它被HOOK掉——的人可以在这个类中添加自己的 GetProcAddress 成员函数。
        if (!fun) throw(function_not_found_exception(name)); //对用户负责一点~
        return fun(arg0); //实在没什么好说的
    }
    template < class R, class A0, class A1 >
    R call ( char const * const name, A0 arg0, A1 arg1 ) {
        typedef R (*fp)(A0,A1);
        fp fun=reinterpret_cast<fp>(GetProcAddress(hmodule,name));
        if (!fun) throw(function_not_found_exception(name));
        return fun(arg0,arg1);
    }
    //依此类推...
};

我说完了,完整的代码在这里:
http://blog.163.com/iamyuguo@126/blog/static/328033302008101524619977/

  评论这张
转发至微博
转发至微博
0   分享到:        
阅读(154)| 评论(0)| 不可引用 |举报

历史上的今天

相关文章

最近读者

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--相关文章--> <#--历史上的今天--> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2012