文章

滴水-day25-静态链接与动态链接

静态链接库与动态链接库

08月12日

静态链接库

通过.lib和.h进行链接的程序一般是静态库

静态不是真正的模块化

是直接把lib中的数据压缩到exe中,在调用.h中提供的方法

cpp要引入头文件。

如果.h重编译了那么exe也需要重编译。不能做到动态更该代码

动态链接库

动态链接库通常是dll文件

dll的优点就在于如果程序需要修改,只需要修改该功能所在的dll,编译dll就可以了,主模块不需要重新编译。

动态链接库也需要.lib文件,该文件是告诉编译器dll中的方法在什么位置。

dll中的函数名称是可以隐藏的,在同级目录下新建一个.def文件,把所有的函数名都在这个文件定义一下。

add @12 类似与这样

// 这里要使用cdecl,因为在dll的头文件中函数的声明是默认的,默认使用的就是cdecl
typedef int(__cdecl *pAdd)(int, int);

HINSTANCE hMoudle = LoadLibrary(L"Dll1.dll");
if (hMoudle == NULL)
{
	std::cout << "错误" << std::endl;
	return 0;
}
pAdd padd = (pAdd)GetProcAddress(hMoudle, (LPCSTR)1);
if (padd == nullptr)
{
	std::cout << padd << std::endl;
	return 0;
}
std::cout << "函数地址----> " << padd << std::endl;
printf("%d\\\\n", padd(1, 2));

DLL与Lib的导入

隐式链接

在调用dll的cpp文件中声明函数


extern "C" __declspec(dllimport) int __stdcall add(int x, int y);
printf("%d\\\\n", add(1, 3));

显式链接

//声明函数指针
typedef int(__stdcall *pAdd)(int, int);
//声明函数指针变量
pAdd padd;
// 加载DLL
HINSTANCE hMoudle = LoadLibrary(L"Dll1.dll");
// 获取函数地址
padd = (pAdd)GetProcAddress(hMoudle, "_add@8");
// 调用函数
int result = padd(1,2);

//这几个步骤可以合起来
HINSTANCE hMoudle = LoadLibrary(L"Dll1.dll");
if (hMoudle == NULL)
{
	std::cout << "错误" << std::endl;
	return 0;
}
pAdd padd = (pAdd)GetProcAddress(hMoudle, "_add@8");
printf("%d\\\\n", padd(1, 2));

License:  CC BY 4.0