关闭

自己写的DllCall类方便dll动态链接库函数调用

标签: dllnullstringshellclassgcc
2862人阅读 评论(2) 收藏 举报

 

/* 
DllCall类,用来方便调用动态链接库内的函数。最初版。
使用方法:
DllCall<FunctionTYPE> SomeCall(动态链接库名,函数名,[函数索引]);
以后正常调用SomeCall.call(参数);
使用前可以用if(SomeCall)来检测是否可调用。
作者:苏晓
时间:2006年5月文件:DllCall.h
*/
#ifndef DLLCALLCLASS__

#define DLLCALLCLASS__
#include 
<string>
#include 
<windows.h>
template 
<typename TYPE>
class DllCall
{
    std::
string DllName;
    std::
string FunctionName;
    
int Index;
    HMODULE dll;
public:
    TYPE call;
    DllCall(std::
string dllname,std::string functionname,int index=-1)
    {
        DllName
=dllname;
        FunctionName
=functionname;
        Index
=index;
        call
=NULL;
        dll
=NULL;
        
get();
    };
    
~DllCall()
    {
        
if(dll)
        {
            
try{
                FreeLibrary(dll);
            }
catch(...)
            {
            };
        };
    };
private:
    
void* Get()
    {
        
if(Index==-1)
        {
            
if(DllName!=""&&FunctionName!="")
            {
                dll
=GetModuleHandle(DllName.c_str());
                
if(dll)
                {
                    
void * ret=GetProcAddress(dll,FunctionName.c_str());
                    CloseHandle(dll);
                    dll
=NULL;
                    
return ret;
                }
else
                {
                    dll
=LoadLibrary(DllName.c_str());
                    
if(dll)
                    {
                        
return GetProcAddress(dll,FunctionName.c_str());
                    }
else
                    {
                        
return NULL;
                    };
                };
            }
else
            {
                
return NULL;
            };
        }
else
        {
            
if(DllName!="")
            {
                dll
=GetModuleHandle(DllName.c_str());
                
if(dll)
                {
                    
void * ret=GetProcAddress(dll,MAKEINTRESOURCE(Index));
                    CloseHandle(dll);
                    dll
=NULL;
                    
return ret;
                }
else
                {
                    dll
=LoadLibrary(DllName.c_str());
                    
if(dll)
                    {
                        
return GetProcAddress(dll,MAKEINTRESOURCE(Index));
                    }
else
                    {
                        
return NULL;
                    };
                };
            }
else
            {
                
return NULL;
            };
        };
    };
    
bool get()
    {
        
if((call=(TYPE)Get()))
        {
            
return true;
        }
else
        {
            
return false;
        };
    };
public:
    
operator int()
    {
        
return (call!=NULL);
    };
};

#endif

/*VC6下测试文件test.cpp*/

#include 
"DllCall.h"
typedef unsigned 
long DWORD;

//DllCall<int (__stdcall*)(int)> mybox2("shell32.dll","",60); //放在全局不行,销毁不正常,VC6现在才觉得它很变态!
DllCall<DWORD(*)(DWORD,DWORD,DWORD,DWORD)> mybox1("user32.dll","MessageBoxA");


int main(int argc, char* argv[])
{
    
    MessageBox(NULL,
"COM",NULL,NULL);
    
    DllCall
<int (__stdcall*)(int)> mybox2("shell32.dll","",60);

    
if(mybox1)
    {
        mybox1.call(NULL,(DWORD)
"HEHE",NULL,NULL);
    };
    
if(mybox2)
    {
        mybox2.call(
0);
    };
    MessageBox(NULL,
"COM",NULL,NULL);
    
return 0;
}

/*
VC6真的是很变态!还是我的机器上的VC6很变态!?还是我的调用约定__stdcall 写错了?优化选项不能打开,否则汇编代码是错误的,调用完毕销毁错误。真是奇怪的很啊。下面是改进版本,GCC,VC通用。推荐用GCC编译器。不会像VC一样出错。
*/

/*
DllCall类,用来方便调用动态链接库内的函数。改进版。
使用方法:
DllCall<FunctionTYPE> SomeCall(动态链接库名,函数名,[函数索引]);
以后正常调用SomeCall.call(参数);
或者SomeCall(参数);
使用前可以用if(SomeCall)来检测是否可调用。
作者:苏晓
时间:2006年5月
*/
#ifndef DLLCALLCLASS__

#define DLLCALLCLASS__
#include 
<string>
#include 
<windows.h>
template 
<typename TYPE>
class DllCall
{
    HMODULE dll;
public:
    TYPE call;
    DllCall(std::
string dllname,std::string functionname,int index=-1)
    {
        std::
string DllName;
        std::
string FunctionName;
        
int Index;
        DllName
=dllname;
        FunctionName
=functionname;
        Index
=index;
        call
=NULL;
        dll
=NULL;
        call
=(TYPE)Get(DllName,FunctionName,Index);
    };
    
~DllCall()
    {
        
if(dll)
        {
            
try{
                FreeLibrary(dll);
            }
catch(...)
            {
            };
        };
    };
private:
    TYPE Get(std::
string DllName,std::string FunctionName,int Index)
    {
        
if(Index==-1)
        {
            
if(DllName!=""&&FunctionName!="")
            {
                dll
=GetModuleHandle(DllName.c_str());
                
if(dll)
                {
                    TYPE ret
=(TYPE)GetProcAddress(dll,FunctionName.c_str());
                    CloseHandle(dll);
                    dll
=NULL;
                    
return ret;
                }
else
                {
                    dll
=LoadLibrary(DllName.c_str());
                    
if(dll)
                    {
                        
return (TYPE)GetProcAddress(dll,FunctionName.c_str());
                    }
else
                    {
                        
return (TYPE)NULL;
                    };
                };
            }
else
            {
                
return (TYPE)NULL;
            };
        }
else
        {
            
if(DllName!="")
            {
                dll
=GetModuleHandle(DllName.c_str());
                
if(dll)
                {
                    TYPE ret
=(TYPE)GetProcAddress(dll,MAKEINTRESOURCE(Index));
                    CloseHandle(dll);
                    dll
=NULL;
                    
return ret;
                }
else
                {
                    dll
=LoadLibrary(DllName.c_str());
                    
if(dll)
                    {
                        
return (TYPE)GetProcAddress(dll,MAKEINTRESOURCE(Index));
                    }
else
                    {
                        
return (TYPE)NULL;
                    };
                };
            }
else
            {
                
return (TYPE)NULL;
            };
        };
    };
public:
    
operator int()
    {
        
return (call!=NULL);
    };
    
operator TYPE()
    {
        
return call;
    };
};

#endif

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:129988次
    • 积分:1871
    • 等级:
    • 排名:千里之外
    • 原创:50篇
    • 转载:7篇
    • 译文:0篇
    • 评论:71条
    文章分类
    最新评论