1. 关于DLL和LIB
文章《LIB和DLL的区别与使用》有介绍,这里做一个总结。
(1)LIB有2种,一种是动态的,一种是静态的
(2)对于静态的LIB,里面包含了函数代码本身,程序编译时直接读取该LIB得到最终的EXE,这样EXE会比较大,更新LIB顺带需要更新EXE
(3)对于动态的LIB,里面仅包含函数的入口和位置,函数的具体实现在DLL中。这样编译得到的EXE相对比较小,因为EXE是在执行的时候才加载DLL里的内容,因此发布的EXE需要附带有相应的DLL和LIB。
2. 编译DLL
以VS2010为例,其提供了两种DLL工程的建立方式(虽然在控制台项目下也可配置为MFC):控制台DLL,基于MFC的DLL
图1-1. 建立DLL工程(两种方式)
图1-2是两种方式的二级菜单,选择静态还是动态LIB,一般是选动态了,原因见上一节
图1-2. 第1种方式的二级菜单可以添加MFC头文件
两种方式实质都差不多,非MFC方式会有个dllmain.cpp文件,其中的dllmain()函数是DLL的进入、退出函数
与普通工程编写一样,但对于接口函数,需要做特殊声明(实际上DLL还可以用来导出类、变量:VC++ MFC DLL动态链接库编写详解)
图1-3. MFC_DLL工程自动生成的提示
给个例子吧
extern "C" _declspec(dllexport) int EncryptF(LPCWSTR lpszInFile, int nKeyIndex,int nStartLine,
int nEndLine, LPCWSTR lpszOutFile)
{
...
}
3. 使用DLL
DLL工程编译后会生成一个DLL和一个LIB,调用该DLL的工程需要知道它们的位置
图1-4. 可以在属性中设置LIB目录,也可在代码中指定
需要首先对DLL用到的函数接口做个声明:
typedef int (WINAPIV *DLL_EncryptF)(LPCWSTR lpszInFile, int nKeyIndex,int nStartLine,
int nEndLine, LPCWSTR lpszOutFile);
其中DLL_EncryptF是自己定义的,一个函数接口定义一种
然后读入DLL,调用该函数:
HMODULE m_hModule = LoadLibrary(L"myDLL.dll");
DLL_EncryptF m_Encrypt;
if(NULL != m_hModule)
m_Encrypt = (DLL_EncryptF)GetProcAddress(m_hModule, "EncryptF");
int encryptFlag;
if(NULL != m_Encrypt)
encryptFlag = m_Encrypt(wcPathLoad, 20, -1, -1, wcPathSave);
FreeLibrary(m_hModule);