我们通常把一些公用函数制作成函数库,供其它程序使用。
函数库分为静态库和动态库两种。
(1)静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。
(2)动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。
本节将进行讲解动态库的显示链接和隐式链接,在下一节说明静态库的引用
1.动态库的显示链接
对应的生成动态库的代码可以写成下面的形式:
#define DLL_API __declspec(dllexport)
extern "C" int DLL_API add(int x, int y)
{
return (x+y);
}
个是写动态库一定要曝露出来的接口,这个一定要注意,没有这句话动态库是不起任何作用的。
生成dll的方法有两种,一种是在建立项目的时候就把他建立成dll,要么就是先建立一个Windows控制台程序,然后设置项目的属性生成dll.
对应的调用动态库的.c文件的写法:
#include "windows.h"
#include "stdio.h"
typedef int(*lpAddFun)(int,int);//typedef定义一个指向函数类型的指针
//先复习一下指向函数的指针
/*如果在程序中定义了一个函数,在编译时,编译系统为函数代码段分配一段存储空间
这段存储空间的起始地址称为这个函数的指针
*/
int main(int argc, char* argv[])
{
char* szStr = "demodll.dll";
WCHAR wszClassName[256];
memset(wszClassName, 0, sizeof(wszClassName));
MultiByteToWideChar(CP_ACP, 0, szStr, strlen(szStr) + 1, wszClassName,
sizeof(wszClassName) / sizeof(wszClassName[0]));
HINSTANCE hDll; //DLL句柄
lpAddFun addFun; //函数指针
//数组名代表首元素地址
hDll = LoadLibrary(wszClassName);
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll, "add");
if(addFun != NULL)
{
int result = (*addFun)(2, 3);
printf("%d\n", result);
}
FreeLibrary(hDll);
}
return 0;
}
这里需要注意的一个问题是 LoadLibrary()对应的形参是一个指向WHAR型的指针,而我们正常的是一个char 字符串,所以上面那些语句进行转化的是。
2.动态库的隐式链接
将生成的.dll和.lib都要放在工程目录下,然后用语句 pragma comment(lib,"... .lib");
然后再把附加库目录和附加依赖项都清除就可以了。