动态链接库
来源:互联网 发布:变脸软件有哪些 编辑:程序博客网 时间: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相同的成员函数,成员函数中通过获得库函数指针调用库函数,这样封装下,显得比较清晰。
函数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);
加载动态库及获得库函数函数指针代码如下:
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(
WINBASEAPI
__out
HMODULE
WINAPI
LoadLibraryW(
#ifdef UNICODE
#define LoadLibrary LoadLibraryW
#else
#define LoadLibrary LoadLibraryA
#endif // !UNICODE
lpLibFileName是动态连接库的名称。
调用函数的例子如下:
//加载动态连接库。