代码实现加载dll,动态调用调用dll接口函数
【背景】
多个模块对外接口都一样,只是内部实现不同,这些模块都被封装成dll,便于管理、开发和维护,调用这些模块的情况随用户操作接口确定调用哪个dll的。
【实现】
dll封装注:
1、dll封装时需要实现从基类继承的虚函数,并导出两个函数供外部调用:a、CreateLidarPlugin函数用于new子类对象供外部使用;b、DestroyLidarPlugin函数用于释放CreateLidarPlugin函数new的对象
2、dll都必须继承一个抽象类RawLiDARDataReader,其大致实现如下:
两个函数指针用于获取子类到处的两个函数
外部调用dll的方式:
- 通过LoadLibaryEx函数加载dll库(dll库存放在exe文件所在文件夹下)
std::string pluginPath; //dll全路径
std::replace(pluginPath.begin(), pluginPath.end(), '/', '\\');//加载dll必须要双斜杠
std::string lidarType = iter->first;
WCHAR pWpluginPath[1024] = { 0 };
MultiByteToWideChar(CP_OEMCP, 0, pluginPath.c_str(), strlen(pluginPath.c_str()) + 1, pWpluginPath, 1024);
HINSTANCE hDll = LoadLibraryEx(pWpluginPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (NULL == hDll) {
//加载dll失败
}
- 通过GetProcAdress函数获取dll向外导出的函数
CreateLiDarPlugin_t* createLidarPlugin = (CreateLiDarPlugin_t*)GetProcAddress(hDll, "CreateLidarPlugin");
if (NULL == createLidarPlugin) {
//从插件中获取函数地址:CreateLidarPlugin 失败"(创建对象的函数)
FreeLibrary(hDll); //释放句柄
}
DestroyLidarPlugin_t* destroyLidarPlugin = (DestroyLidarPlugin_t*)GetProcAddress(hDll, "DestroyLidarPlugin");
if (NULL == destroyLidarPlugin) {
// "从插件中获取函数地址:DestroyLidarPlugin 失败"(释放对象的函数) FreeLibrary(hDll); //释放句柄
}
- 通过上面获取到的函数创建当前处理所用的对象
RawLiDARDataReader* rawLidarDataReader = createLidarPlugin();
if (NULL == rawLidarDataReader)
{
// 创建激光解析器对象失败
}