【原创】C++创建和使用动态链接库之常规DLL
MFC常规DLL中可以使用C++和MFC类库及函数,但其导出接口必须是C函数,不能导出C++函数和类
MFC常规DLL可以在MFC程序和大多数Win32程序中使用
- 创建常规DLL
新建工程 选择MFC APPWizard(dll),工程名为ShowTime,点击确定
进入下一个步骤要创建的DLL的类型,如图所示:
动态链接库和MFC静态链接:这种DLL在链接过程中会将使用到得MFC类库复制一份到最终的DLL文件中
最终生成的DLL比较庞大且加载时不是很方便,但它可以在没有MFC类库DLL文件的机器上使用
动态链接库使用共享MFC DLL:这种DLL不会将用到的MFC类库复制到最终生成的DLL中,因此最终的DLL比较小,加载也很方便,但在没有MFC类库DLL文件的机器上无法使用,必须有MFC类库的支持
MFC扩展DLL(使用共享MFC DLL):MFC扩展DLL可以导出C++类以及MFC派生类,使用这种DLL必须有MFC类库的支持
选择动态链接库使用共享MFC DLL选项,单机完成。程序会自动生成对应的文件
其中ShowTime.h和ShowTime.cpp以及ShowTime.def是我们要用到的
在ShowTime.h中加入函数的声明
void ShowTime();
在ShowTime.cpp中加入函数的实现
void ShowTime()
{CString strtime;SYSTEMTIME systime;GetLocalTime(&systime);strtime.Format("现在时间是: %d 年 %d 月 %d 日 %d 时 %d 分 %d 秒",
systime.wYear,systime.wMonth,systime.wDay,systime.wHour,systime.wMinute,systime.wMilliseconds);MessageBox(NULL,strtime,"Time",NULL);
}
使用显示链接调用DLL时,用GetProcAddress函数指定的函数名必须是编译后经过编译器重命名的函数名,而不是源文件中定义的函数名。而程序员不大可能去了解每一个经过重命名的导出函数名,所幸微软给出了一个很好的解决方法,那就是在编写动态库的同时编写一个def为后缀的编译命名参考文件,如果动态库中有该文件,则编译器会根据该文件指定的函数名来导出动态库中的函数
每个def文件至少必须包含以下模块
- LIBRARY "DLL名称" //默认生成的def文件会自动添加对应的DLL名字
- EXPORTS语句列出被导出的函数的名字,被导出的函数可以和一个数字序号相对应
本例只需在EXPORTS语句下面添加一个函数ShowTime @1
在ShowTime.def中添加要导出的函数名
编译并链接,在工程的debug目录里会生成ShowTime.dll和ShowTime.lib文件
- 使用常规DLL(显示链接)
因为常规DLL导出的是标准C函数,可以被非MFC程序使用,所以这里创建了一个Win32控制台程序
新建一个Win32 Console Application工程,工程名为test
把前面生成的ShowTime.dll拷贝到工程目录中,在debug目录再拷贝一份防止直接运行exe时找不到DLL
添加一个cpp文件,输入如下代码
#include <windows.h>int main()
{HINSTANCE hInstance; //HINSTANCE需要包含windows.h
typedef char* (Fun)(); //定义函数原型Fun* pFun; //声明函数指针
//返回由LoadLibrary加载的动态链接库的实例句柄
hInstance=LoadLibrary("ShowTime");
//找到DLL中ShowTime函数的地址,函数名调用
//pFun=(Fun*)GetProcAddress(hInstance,"ShowTime");
//使用数字序号方式,可明显加快函数的调用
pFun=(Fun*)GetProcAddress(hInstance,(LPCSTR) 1);(*pFun)(); //调用函数
FreeLibrary(hInstance); //释放调用的DLL资源
return 0;
}
运行效果如图所示源程序下载地址