启动优化之动态库延迟加载

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/L_Andy/article/details/84926579

程序启动过程中加载过多动态库会导致启动变慢,尤其是刚开机时启动程序,加载过多的dll会占用IO,这时候系统IO通常是非常繁忙的,会拖慢启动速度。

        动态库加载包括静态加载和动态加载, 静态加载就是使用lib,代码生成过程中链接用的。静态加载可以使用动态库中的导出函数和导出类,但是静态加载是程序启动时加载动态库,会占用启动时间。动态加载用LoadLibrary函数加载动态库,可以随时动态加载DLL,不需要lib,不需要在启动时加载可以节省启动时间。但是只能用GetProcAddress获取导出函数,对导出类通常是无能为力的,相对来说GetProcAddress使用也没有静态加载方便。

        动态库延迟加载可以解决上述缺点,既可以不在启动时加载,不占用启动时间,也不需要GetProcAddress获取导出函数,可以直接使用导出函数和导出类(尤其是第三方DLL只提供导出类的情况下)。总体来说即灵活快速,又方便使用。

        动态库延迟加载节省了启动时间,也节省了系统资源,刚开机时IO慢时不进行加载,到后面IO不忙的时候加载DLL就会快很多,所以延迟加载并不一定造成后面模块使用时卡顿。

延迟加载设置:

在vs项目属性--配置属性--链接器--输入--延迟加载的DLL中设置需要延迟加载的DLL,可以设置多个,用分号隔开。
在vs项目属性--配置属性--链接器--输入--附加依赖项 填写DLL对应的lib,或者代码中用#pragma comment( lib,"..\\Lib\\LiveStreamTrans.lib" ) 来加载lib,这里只需要延迟加载的DLL的lib,DLL依赖的但又没有在项目中直接使用的其他DLL的lib不需要。
在代码中手动加载DLL,如果有多个DLL,需要包含DLL的依赖DLL,并且要按依赖顺序加载,被依赖的先加载,加载使用LoadLibrary函数,如果不按依赖顺序加载会导致LoadLibrary失败。
要注意控制加载时机,DLL函数或者类的使用不能早于该DLL被LoadLibrary,通常如果是懒加载方式,是该功能模块使用时加载,这样比较节省资源;
加载相同动态库不要加载多次,外部可以用静态变量判断一下是否加载过。
示例代码如下:

void LiveFuncMgr::LoadAudioDll()
{
	LOGI("{}", __FUNCTION__);
 
	static const vector<wstring> delay_load_dlls = {
			L"w32-pthreads.dll",
 
			L"postproc-55.dll",
			L"swresample-3.dll",
			L"swscale-5.dll",
			L"avcodec-58.dll",
			L"avdevice-58.dll",
			L"avfilter-7.dll",
			L"avformat-58.dll",
			L"avutil-56.dll",
 
			L"libfaac.dll",
			L"libfaad2.dll",
			L"libglog.dll",
			L"libogg.dll",
			L"libspeex.dll",
			L"libspeexdsp.dll",
			L"AudioLive.dll"
			//L"LiveStreamTrans.dll"
	};
 
	std::wstring wstrDir = util::get_exe_dirw() + L"Plugins\\Live\\deps\\";
 
	for (size_t i = 0; i < delay_load_dlls.size(); ++i)
	{
		util::load_library((wstrDir + delay_load_dlls[i]).c_str());
	}
}
 
void Init()
{
	static bool s_dll_loaded = false;
	if (!s_dll_loaded)
	{
		LiveFuncMgr::GetInstance()->LoadAudioDll();
		s_dll_loaded = true;
	}
}
 

猜你喜欢

转载自blog.csdn.net/L_Andy/article/details/84926579