动态链接库

来源:互联网 发布:变脸软件有哪些 编辑:程序博客网 时间:2024/06/07 08:45
 qt类库中QLibrary就是用于解决qt调用动态库.dll问题,假设有一动态库文件为dllName.dll,其中有一库函数为 int add(int x,int y);

加载动态库及获得库函数函数指针代码如下:

view plain
#include ...  
typedef int (*AddFunc)(int x,int y);//定义函数指针类型  
AddFunc subAdd = NULL;//定义函数指针变量  
int main(int argc,char *argv[])  
{  
    QApplication app(argc,argv);  
    QLibrary dllLib("dllName.dll");  
    if(!dllLib.load())  
    {  
         return -1;  
    }  
    else  
    {  
         subAdd = (AddFunc)dllLib.resolve("add");  
         if(subAdd == NULL)  
         {  
               return -1;  
         }  
         else  
         {   
              printf("sum = %d",subAdd(1,1));  
              //print  sum = 2;  
         }  
    }  
    int ret = app.exec();  
    return ret;  
}  
因为正常应用中加载的dll中会有比较多的库函数,这个时候我们可以考虑自定义一个类CDllLibrary,继承QLibrary,对dll库加载和获得库函数函数指针在该类中实现,该类提供与dll相同的成员函数,成员函数中通过获得库函数指针调用库函数,这样封装下,显得比较清晰。

需要特别注意的是:qt加载其他不同编译器的dll时,对加载的库函数有要求,需要在库函数声明或定义前加extern "C" _declspec(dllexport),如上面例子加声明:  extern "C" _declspec(dllexport)  int add(int x,int y);因为对于C,大多数的编译结果差不多,可以通用。详细见qt Assistant QLibrary。




LoadLibrary函数
随着软件规模的扩大,要求的功能也是越来越多,开发人员的参与也是越来越多。因此软件的功能划分,就成为了现代软件工程的重大任务,还有软件开发的并行性也越来越重要。为了解决这些问题,大家都会看到IT硬件发展非常迅速,功能也越来越复杂,但硬件中发展明显提高在于采用IC的方式来实现复杂的功能,也就是把大部份功能集成到一起,只要给出一些引脚就可以实现产品了。而软件中有没有相同于硬件中的IC呢?我想是应有的,就是动态连接库了。在Windows这座大厦里,很多基石就是动态连接库构成的。一个动态连接库就封装了特别复杂的功能,使用者不必关心它是怎么样实现的。当然,这样也可以让不同的开发者同时开发产品,提高软件开发的速度。要使用动态连接库里的函数,就需要使用LoadLibrary函数来加载动态连接库,使用函数GetProcAddress来获取功能函数的地址。
 

函数LoadLibrary声明如下:
 
WINBASEAPI
__out
HMODULE
WINAPI
LoadLibraryA(
    __in LPCSTRlpLibFileName
    );
WINBASEAPI
__out
HMODULE
WINAPI
LoadLibraryW(
    __in LPCWSTRlpLibFileName
    );
#ifdef UNICODE
#define LoadLibrary LoadLibraryW
#else
#define LoadLibrary LoadLibraryA
#endif // !UNICODE
 
lpLibFileName是动态连接库的名称。
 
调用函数的例子如下:
 //加载动态连接库。

void TestLoadDLL(void)
{
     //加载动态连接库。
       HMODULE hDllLib = LoadLibrary(_T("Kernel32.dll"));
        if (hDllLib)
        {
              //获取动态连接库里的函数地址。
             FARPROC fpFun = GetProcAddress(hDllLib,"GetVersion");
              
              //调用函数运行。
             DWORD dwVersion = (*fpFun)();
              
              //获取WINDOWS的版本。
              DWORD dwWindowsMajorVersion =(DWORD)(LOBYTE(LOWORD(dwVersion)));
              DWORD dwWindowsMinorVersion =(DWORD)(HIBYTE(LOWORD(dwVersion)));
              
              //显示。
              const int nBufSize = 512;
              TCHAR chBuf[nBufSize];
              ZeroMemory(chBuf,nBufSize);

              wsprintf(chBuf,_T("显示版本:%d,%d\r\n"),
                   dwWindowsMajorVersion,dwWindowsMinorVersion);
              OutputDebugString(chBuf);

              //释放动态连接库。
              FreeLibrary(hDllLib);
       }
 }

0 0
原创粉丝点击