#include "ToolDepository.h"
// QT运行库相关的文件夹和dll名称(用于识别tools的时候进行排除,仅用于Qt6)
#define QT_PLATFORMS "platforms"
#define QT6_DEBUG_DLL1 "Qt6Cored.dll"
#define QT6_DEBUG_DLL2 "Qt6Guid.dll"
#define QT6_DEBUG_DLL3 "Qt6Widgetsd.dll"
#define QT6_RELEASE_DLL1 "Qt6Core.dll"
#define QT6_RELEASE_DLL2 "Qt6Gui.dll"
#define QT6_RELEASE_DLL3 "Qt6Widgets.dll"
// 内置的工具的默认分类名称(包括Port工具、注释工具、Goto工具等)
#define BUILDIN_CATEGORY_NAME ("内置工具")
// 工具仓库实例
ToolDepository toolDepository;
ToolDepository::ToolDepository()
{
}
ToolDepository::~ToolDepository()
{
}
////////////////////////////////////////////////////////////
// 加载文件中保存的工具信息
bool ToolDepository::LoadTools()
{
// m_TotalTools.clear();
// 确保只加载一次
if (m_TotalTools.size() > 0)
{
return true;
}
// 从文件中加载工具信息
this->LoadFromFile(DEFAULT_TOOL_PATH);
// 2021-3-29增加,直接在内部生成port工具,不从外部加载了
this->createPortTool();
// 2022-3-15,增加内部生成的Comment工具
this->createCommentTool();
// 2022-3-25,内部生成Goto工具
this->createGotoTool();
// 2022-4-18 生成内置的并行计算工具
this->createParallelTool();
// 2022-8-22 生成内置的ForLoop工具
this->createForLoopTool();
// 2022-9-2 生成内置的Wait工具
this->createWaitTool();
return true;
}
////////////////////////////////////////////////////////////
// 从文件中加载工具信息
bool ToolDepository::LoadFromFile(const QString& strPath)
{
QDir dir(strPath);
if (!dir.exists() || strPath.indexOf("platforms") > 1)
return false;
// 取所有的文件和文件名,但是去掉.和..的文件夹
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
// 文件夹优先
dir.setSorting(QDir::DirsFirst);
QFileInfoList list = dir.entryInfoList();
int i = 0;
while(i < list.size())
{
QFileInfo fileInfo = list.at(i);
bool bisDir = fileInfo.isDir();
if (bisDir)
{
LoadFromFile(fileInfo.filePath());
}
else
{
QString strFileName = fileInfo.fileName();
// 加载所有的dll工具
if (strFileName.endsWith(TOOL_EXT)
// 跳过Qt6相关运行Dll
//&& strFileName.compare(QT6_DEBUG_DLL1) != 0
//&& strFileName.compare(QT6_DEBUG_DLL2) != 0
//&& strFileName.compare(QT6_DEBUG_DLL3) != 0
//&& strFileName.compare(QT6_RELEASE_DLL1) != 0
//&& strFileName.compare(QT6_RELEASE_DLL2) != 0
//&& strFileName.compare(QT6_RELEASE_DLL3) != 0
)
{
QString strDllFullPath = fileInfo.absoluteFilePath();
// 取出新的dll工具信息,加入到集合中
if (!ParseToolsFromDll(strDllFullPath, strFileName))
{
// Report Error
// 2021-8-5,居然发现了一个隐藏多年的bug,此处会导致代码死循环
i++;
continue;
}
}
}
i++;
};
return true;
}
/////////////////////////////////////////////////////////////
// 从dll中提取工具信息
bool ToolDepository::ParseToolsFromDll(const QString& strDllPath, const QString& strDllName)
{
// 加载Dll
// 2021-01-17,设计思路调整,此处工具仓库加载完工具信息后,直接释放掉,后面用到的时候再加载,优化资源占用
QLibrary dllTool(strDllPath);
if (!dllTool.load())
{
vWarning() << "[Error] ToolDepository::ParseToolsFromDll - load [" << strDllName << "] failed, Reason:"
<< dllTool.errorString();
return false;
}
// 调用NewToolPtr接口
typedef DllTool* (*GETTOOL)();
GETTOOL GetTool = (GETTOOL)dllTool.resolve(FUNCTION_GETTOOL);
if (GetTool == nullptr)
{
qDebug() << "[Error] ToolDepository::ParseToolsFromDll - [" << strDllName << "] GetTool failed, Reason:"
<< dllTool.errorString();
return false;
}
// 获取指针
DllTool* pDllPtr = GetTool();
if (pDllPtr == nullptr)
{
qDebug() << "[Error] ToolDepository::ParseToolsFromDll - [" << strDllName << "] GetTool failed, Reason:"
<< dllTool.errorString();
return false;
}
// 初始化工具信息
// 2021-8-2 改成了将dll中的参数值传递进exe中,否则event带不进来
pDllPtr->InitTool();
// 获取工具描述
const DLL_TOOL_DESC& toolDescriotion = pDllPtr->Description();
STATIC_TOOL newStaticTool;
newStaticTool.Type = toolDescriotion.Type;
newStaticTool.strName = toolDescriotion.strName;
newStaticTool.strAliasName = toolDescriotion.strAliasName;
newStaticTool.strCategory = toolDescriotion.strCategory;
newStaticTool.strVersion = toolDescriotion.strVersion;
newStaticTool.strDllPath = strDllPath;
newStaticTool.strInfo = toolDescriotion.strInfo;
// 对于某些未设置别名的工具,就将工具名称设置为别名
if (newStaticTool.strAliasName.isEmpty())
{
newStaticTool.strAliasName = newStaticTool.strName;
}
// 获取工具接口信息
for (int i = 0; i < pDllPtr->GetInterfaceSize(); i++)
{
const DLL_INF& dllinf = pDllPtr->Interface(i);
STATIC_INTERFACE newStaticInf;
newStaticInf.strName = dllinf.strName;
newStaticInf.Direction = dllinf.Direction;
newStaticInf.Discard = dllinf.Discard;
newStaticInf.Type = dllinf.Type;
// 2021-8-2 ,将value改成了从dll中全部复制,否则dll中的event带不进来
//newStaticInf.value = dllinf.value;
//newStaticInf.value.Ptr = nullptr;
// 2022-9-19,如果是Event类型的接口,此处要把Dll中的Event拷贝进来
// MEMO:值在这里拷贝没有意义,因为执行到这里的时候,Tool那边是采用空值初始化的,这里的Value值都是空的
// 这里无需复制,在PouScene中添加完工具执行 pNewTool->pDllPtr->InitTool() 的时候才是带值初始化
// 而且原则上exe中是不保存dll中的值的,所以需要用到dll中值的时候应该直接过去取,而不是拷贝到exe中
// 所以Event的值是在Task绑定event句柄的时候,直接从dll中取值了,而不是从这里拷贝过来
//if (newStaticInf.Type == INF_TYPE::INF_TYPE_EVENT)
//{
// newStaticInf.value.Ptr = dllinf.value.Ptr;
//}
// newStaticInf.eventTrigger = dllinf.eventTrigger;
newStaticInf.value.passMode = dllinf.value.passMode;
newStaticInf.value.type = dllinf.value.type;
newStaticInf.nIndex = i;
newStaticInf.bEnable = dllinf.bEnable;
newStaticTool.staticInterfaces.push_back(newStaticInf);
}
//newTool.hIcon = (HICON)::LoadImage(hDllTool, MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
//g_imagelist->Add(newTool.hIcon);
// 调用ReleaseToolPtr接口
typedef void (*RELEASETOOL)();
RELEASETOOL ReleaseTool = (RELEASETOOL)dllTool.resolve(FUNCTION_RELEASETOOL);
if (ReleaseTool == nullptr)
{
// CUtility::CriticalMessageBox(_T("获取ReleaseToolPtr 失败!\n\n%s"), strDllPath.GetString());
qDebug() << "[Error] ToolDepository::ParseToolsFromDll - [" << strDllName << "] ReleaseTool failed, Reason:" << dllTool.errorString();
return false;
}
// 2021-3-29 增加,只加入标准类型工具
if (newStaticTool.isStandardTool())
{
// 添加到工具集中
AddToCategory(newStaticTool, toolDescriotion.strCategory);
m_toolDllPaths.insert(newStaticTool.strName, newStaticTool.strDllPath);
qDebug() << "ToolDepository::ParseToolsFromDll - Add [" << strDllName << "] to toolbox.";
}
else
{
qDebug() << "ToolDepository::ParseToolsFromDll - Ignore [" << strDllName << "], Reason: is not standard tool.";
}
// 释放工具内存
ReleaseTool();
// dllTool.unload();
return true;
}
/////////////////////////////////////////////////////////////
// 将工具信息添加到Category中
bool ToolDepository::AddToCategory(const STATIC_TOOL& newTool, const QString& strCategoryName)
{
// 找到对应的Category,添加
for (int i = 0; i < m_TotalTools.size(); i++)
{
TOOL_CATEGORY& cate = m_TotalTools[i];
if (cate.strName.compare(strCategoryName) == 0)
{
cate.staticTools.push_back(newTool);
return true;
}
}
// 如果没找到,则建一个新的工具集
TOOL_CATEGORY cate;
cate.strName = strCategoryName;
cate.staticTools.push_back(newTool);
m_TotalTools.push_back(cate);
return true;
}
///
/// 2021-3-29增加,直接在内部生成port工具,不从外部加载了
///
void ToolDepository::createPortTool()
{
// Output
m_toolPortOutput.Type = TOOL_TYPE::TOOL_TYPE_PORT_OUTPUT;
m_toolPortOutput.strName = ("OutputPort");;
m_toolPortOutput.strAliasName = m_toolPortOutput.strName;
m_toolPortOutput.strVersion = ("2.0");
m_toolPortOutput.strDllPath = ("");
m_toolPortOutput.strInfo = ("Output port tool.");
STATIC_INTERFACE newStaticInf;
newStaticInf.strName = ("");
newStaticInf.Direction = INF_DIRECTION::INF_DIR_OUT;
newStaticInf.Type = INF_TYPE::INF_TYPE_UNKNOWN;
newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_UNKNOWN;
newStaticInf.value.type = VALUE_TYPE::Type_Unknown;
newStaticInf.value.Ptr = nullptr;
newStaticInf.nIndex = 0;
newStaticInf.bEnable = true;
m_toolPortOutput.staticInterfaces.push_back(newStaticInf);
AddToCategory(m_toolPortOutput, BUILDIN_CATEGORY_NAME);
// Input
m_toolPortInput.Type = TOOL_TYPE::TOOL_TYPE_PORT_INPUT;
m_toolPortInput.strName = ("InputPort");;
m_toolPortInput.strAliasName = m_toolPortInput.strName;
m_toolPortInput.strVersion = ("2.0");
m_toolPortInput.strDllPath = ("");
m_toolPortInput.strInfo = ("Input port tool.");
newStaticInf.strName = ("");
newStaticInf.Direction = INF_DIRECTION::INF_DIR_IN;
newStaticInf.Type = INF_TYPE::INF_TYPE_UNKNOWN;
newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_UNKNOWN;
newStaticInf.value.type = VALUE_TYPE::Type_Unknown;
newStaticInf.value.Ptr = nullptr;
newStaticInf.nIndex = 0;
newStaticInf.bEnable = true;
m_toolPortInput.staticInterfaces.push_back(newStaticInf);
AddToCategory(m_toolPortInput, BUILDIN_CATEGORY_NAME);
}
///
/// 2022-3-13 内置注释工具
///
void ToolDepository::createCommentTool()
{
m_toolComment.Type = TOOL_TYPE::TOOL_TYPE_COMMENT;
m_toolComment.strName = ("Comment");;
m_toolComment.strAliasName = m_toolComment.strName;
m_toolComment.strVersion = ("1.0");
m_toolComment.strDllPath = ("");
m_toolComment.strInfo = ("DoubleClick to edit content.");
AddToCategory(m_toolComment, BUILDIN_CATEGORY_NAME);
}
///
/// 2022-3-22 生成内置的Goto工具
///
void ToolDepository::createGotoTool()
{
m_toolGoto.Type = TOOL_TYPE::TOOL_TYPE_GOTO;
m_toolGoto.strName = ("Goto");;
m_toolGoto.strAliasName = m_toolGoto.strName;
m_toolGoto.strVersion = ("1.0");
m_toolGoto.strDllPath = ("");
m_toolGoto.strInfo = ("");
// 输入接口固定为bool
STATIC_INTERFACE newStaticInf;
newStaticInf.strName = ("bool"); // 虽然设置了,但是不显示输入接口名称
newStaticInf.Direction = INF_DIRECTION::INF_DIR_IN;
newStaticInf.Type = INF_TYPE::INF_TYPE_STANDARD;
newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
newStaticInf.value.type = VALUE_TYPE::Type_Bool;
// 输入接口默认值为false
// m_bDefaultGotoInput = false;
// newStaticInf.value.Ptr = (void**)&m_bDefaultGotoInput;
newStaticInf.value.setValue(false);
newStaticInf.nIndex = 0;
newStaticInf.bEnable = true;
newStaticInf.bShowName = false; // Goto的输入接口不显示名字
m_toolGoto.staticInterfaces.push_back(newStaticInf);
// 输出接口为空,等待绑定
newStaticInf.reset();
newStaticInf.strName = ("Output");
newStaticInf.Direction = INF_DIRECTION::INF_DIR_OUT;
newStaticInf.Type = INF_TYPE::INF_TYPE_TOOL; // 设置为Tool的输出接口,用于链接Tool
newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
newStaticInf.value.type = VALUE_TYPE::Type_Tool; // 设置为Tool类型,表示连接到Tool类型的接口
newStaticInf.value.Ptr = nullptr;
newStaticInf.nIndex = 0;
newStaticInf.bEnable = true;
newStaticInf.bShowName = false; // Goto的输出接口默认不显示名字,绑定后才显示
m_toolGoto.staticInterfaces.push_back(newStaticInf);
AddToCategory(m_toolGoto, BUILDIN_CATEGORY_NAME);
}
///
/// 2022-4-18 生成内置的并行计算工具
///
void ToolDepository::createParallelTool()
{
// 工具信息
m_toolParallel.Type = TOOL_TYPE::TOOL_TYPE_PARALLEL;
m_toolParallel.strName = ("Parallel");;
m_toolParallel.strAliasName = m_toolParallel.strName;
m_toolParallel.strVersion = ("1.0");
m_toolParallel.strDllPath = ("");
m_toolParallel.strInfo = ("");
// 接口信息
STATIC_INTERFACE newStaticInf;
// 2022-4-28 屏蔽,为了和标准工具统一,输入接口移至到运行时动态增加
// 输入接口(用于绑定Goto,Top类型)
//newStaticInf.strName = ("Top.In"); // 虽然设置了,但是不显示输入接口名称
//newStaticInf.Direction = INF_DIRECTION::INF_DIR_IN;
//newStaticInf.Type = INF_TYPE::INF_TYPE_TOP;
//newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
//newStaticInf.value.type = VALUE_TYPE::Type_Tool; // 设置为Tool类型,表示只能接收Goto连接
//newStaticInf.value.Ptr = nullptr;
//newStaticInf.nIndex = 0;
//newStaticInf.bEnable = true;
//newStaticInf.bShowName = false; // 并行工具的输入接口不显示名字
//m_toolParallel.staticInterfaces.push_back(newStaticInf);
//newStaticInf.reset();
//newStaticInf.strName = ("Tool.End");
//newStaticInf.Direction = INF_DIRECTION::INF_DIR_OUT;
//newStaticInf.Type = INF_TYPE::INF_TYPE_TOOL; // 设置为Tool的输出接口,用于链接Tool
//newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
//newStaticInf.value.type = VALUE_TYPE::Type_Tool; // 设置为Tool类型,表示连接到Tool类型的接口
//newStaticInf.value.Ptr = nullptr;
//newStaticInf.nIndex = 0;
//newStaticInf.bEnable = true;
//newStaticInf.bShowName = false; // 输出接口默认不显示名字
//m_toolParallel.staticInterfaces.push_back(newStaticInf);
AddToCategory(m_toolParallel, BUILDIN_CATEGORY_NAME);
}
///
/// 2022-8-22 生成内置的For循环工具
///
void ToolDepository::createForLoopTool()
{
// 工具信息
m_toolForLoop.Type = TOOL_TYPE::TOOL_TYPE_FORLOOP;
m_toolForLoop.strName = ("ForLoop");;
m_toolForLoop.strAliasName = m_toolForLoop.strName;
m_toolForLoop.strVersion = ("1.0");
m_toolForLoop.strDllPath = ("");
m_toolForLoop.strInfo = ("");
// 接口信息
STATIC_INTERFACE newStaticInf;
//// 默认ToolEnd接口,用于链接循环工具
//newStaticInf.strName = ("Tool.End");
//newStaticInf.Direction = INF_DIRECTION::INF_DIR_OUT;
//newStaticInf.Type = INF_TYPE::INF_TYPE_TOOL; // 设置为Tool的输出接口,用于链接Tool
//newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
//newStaticInf.value.type = VALUE_TYPE::Type_Tool; // 设置为Tool类型,表示连接到Tool类型的接口
//newStaticInf.value.Ptr = nullptr;
//newStaticInf.nIndex = 1;
//newStaticInf.bEnable = true;
//newStaticInf.bShowName = false; // 输出接口默认不显示名字
//m_toolForLoop.staticInterfaces.push_back(newStaticInf);
// 默认size输入接口,用于确定循环体的执行次数
newStaticInf.strName = ("size"); // size接口名称
newStaticInf.Direction = INF_DIRECTION::INF_DIR_IN;
newStaticInf.Type = INF_TYPE::INF_TYPE_STANDARD;
newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
newStaticInf.value.type = VALUE_TYPE::Type_Int;
// 输入接口不需要默认值,全靠上级接口Link进来
// newStaticInf.value.setValue(0);
newStaticInf.nIndex = 0;
newStaticInf.bEnable = true;
newStaticInf.bShowName = true; // 显示接口名称
m_toolForLoop.staticInterfaces.push_back(newStaticInf);
// 默认index输出接口,用于输出当前For循环的index
newStaticInf.strName = ("index"); // Index接口名称
newStaticInf.Direction = INF_DIRECTION::INF_DIR_OUT;
newStaticInf.Type = INF_TYPE::INF_TYPE_STANDARD;
newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
newStaticInf.value.type = VALUE_TYPE::Type_Int;
//// 输出接口默认值为0(不需要默认值,运行时再设置)
//newStaticInf.value.setValue(0);
newStaticInf.nIndex = 1;
newStaticInf.bEnable = true;
newStaticInf.bShowName = true; // 显示接口名称
m_toolForLoop.staticInterfaces.push_back(newStaticInf);
AddToCategory(m_toolForLoop, BUILDIN_CATEGORY_NAME);
}
///
/// 2022-9-2 生成内置的等待Event工具
///
void ToolDepository::createWaitTool()
{
// 工具信息
m_toolWait.Type = TOOL_TYPE::TOOL_TYPE_WAIT;
m_toolWait.strName = ("Wait");;
m_toolWait.strAliasName = m_toolForLoop.strName;
m_toolWait.strVersion = ("1.0");
m_toolWait.strDllPath = ("");
m_toolWait.strInfo = ("");
// 接口信息
STATIC_INTERFACE newStaticInf;
// 默认waitValue输出接口,用于输出工具当前等待的值
newStaticInf.strName = ("waitValue"); // 接口名称
newStaticInf.Direction = INF_DIRECTION::INF_DIR_OUT;
newStaticInf.Type = INF_TYPE::INF_TYPE_STANDARD;
newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
newStaticInf.value.type = VALUE_TYPE::Type_Int;
// 接口默认值
// newStaticInf.value.setValue(0);
newStaticInf.nIndex = 0;
newStaticInf.bEnable = true;
newStaticInf.bShowName = true; // 显示接口名称
m_toolWait.staticInterfaces.push_back(newStaticInf);
// 默认waitTime输出接口,用于输出当前启动后等待的总时长
newStaticInf.strName = ("waitTime"); // 接口名称
newStaticInf.Direction = INF_DIRECTION::INF_DIR_OUT;
newStaticInf.Type = INF_TYPE::INF_TYPE_STANDARD;
newStaticInf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
newStaticInf.value.type = VALUE_TYPE::Type_Int;
//// 输出接口默认值为0(不需要默认值,运行时再设置)
//newStaticInf.value.setValue(0);
newStaticInf.nIndex = 1;
newStaticInf.bEnable = true;
newStaticInf.bShowName = true; // 显示接口名称
m_toolWait.staticInterfaces.push_back(newStaticInf);
AddToCategory(m_toolWait, BUILDIN_CATEGORY_NAME);
}
///
/// 根据名称,获取工具 (根据名字或者曾用名)
///
///
///
TOOL* ToolDepository::getToolByName(QString strName)
{
TOOL* pTool = nullptr;
for (int i = 0; i < toolDepository.m_TotalTools.size(); i++)
{
const TOOL_CATEGORY& cate = toolDepository.m_TotalTools[i];
for (int j = 0; j < cate.staticTools.size(); j++)
{
const STATIC_TOOL& tool = cate.staticTools[j];
if (tool.strName == strName || tool.strAliasName == strName)
{
pTool = new TOOL(&tool);
}
}
}
return pTool;
}
///
/// 获取指定DLL的指针
///
///
///
DllTool* ToolDepository::GetToolPtr(const QString& strToolName)
{
const QString& strDllPath = GetDllPathByName(strToolName);
if (strDllPath.isEmpty())
{
return nullptr;
}
// 加载指定dll
QLibrary dllTool(strDllPath);
if (!dllTool.load())
{
return nullptr;
}
// 调用GetToolPtr接口
typedef DllTool* (*GETTOOL)();
GETTOOL GetTool = (GETTOOL)dllTool.resolve(FUNCTION_GETTOOL);
if (GetTool == nullptr)
{
return nullptr;
}
// 获取指针
DllTool* pDllPtr = GetTool();
if (pDllPtr == nullptr)
{
return nullptr;
}
return pDllPtr;
}
///
/// 获取指定DLL的全路径
///
///
///
QString ToolDepository::GetDllPathByName(const QString& strToolName)
{
if (m_toolDllPaths.contains(strToolName))
{
return m_toolDllPaths.value(strToolName);
}
else
{
return "";
}
}
////////////////////////////////////////////////
//// 释放工具dll
//void CToolManager::FreeToolsLibrary()
//{
// for (unsigned int i = 0; i < m_TotalTools.size(); i++)
// {
// TOOL_CATEGORY& cate = m_TotalTools[i];
//
// for (unsigned int j = 0; j < cate.Tools.size(); j++)
// {
// TOOL& mtool = cate.Tools[j];
// mtool.Interfaces.clear();
//
// // RELEASE_BUFFER(mtool.pDllPtr);
//
// //// 加载dll
// //if (mtool.hDllTool)
// //{
// // // 调用Release接口
// // typedef void(*RELEASE)();
// // RELEASE Release = (RELEASE)GetProcAddress(mtool.hDllTool, FUNCTION_RELEASE);
// // if (Release)
// // {
// // Release();
// // }
//
// FreeLibrary(mtool.hDllTool);
// //}
// }
// cate.Tools.clear();
//
// }
// m_TotalTools.clear();
//}
//
////////////////////////////////////////////////////////
//// 检测Tool的有效性
//bool ToolDepository::ValidateTool(const TOOL& toolInfo)
//{
// // 加载Dll
// QLibrary dllTool(toolInfo.strDll);
// if (!dllTool.load())
// {
// // CUtility::CriticalMessageBox(_T("如下工具缺失,加载存档失败!\n\n%s"), toolInfo.strDll);
// return false;
// }
//
// // 调用Description接口
// typedef const DLL_TOOL_DESC& (*DESCRIPTION)();
// DESCRIPTION Description = (DESCRIPTION)dllTool.resolve(FUNCTION_DESCRIPTION);
// if (Description == nullptr)
// {
// // 获取版本号失败
// // CUtility::CriticalMessageBox(_T("获取版本号失败!\n\n%s"), toolInfo.strDll);
// return false;
// }
//
// // 校验版本号
// const DLL_TOOL_DESC& toolDescriotion = Description();
// if (toolInfo->strVersion.compare(toolDescriotion.strVersion) != 0)
// {
// //// 版本号不一致
// //CUtility::CriticalMessageBox(_T("版本号不一致!\n\n%s \r\n需要版本号为:%s\r\n本地文件版本号为:%s"),
// // toolInfo.strDll, toolInfo.strVersion, toolDescriotion.strVersion);
//
// return false;
// }
//
// // FreeLibrary(hDllTool);
//
// return true;
//}