41 bool isSomethingSimilarLoaded(
const std::string& libName)
const;
43 std::map<std::string, std::shared_ptr< QLibrary > > m_handles;
46 std::vector<std::string> m_supplementarySearchPath;
49DynamicLibrariesManagerPrivate::DynamicLibrariesManagerPrivate() :
51 m_supplementarySearchPath()
55bool DynamicLibrariesManagerPrivate::isSomethingSimilarLoaded(
const std::string& libName)
const
57 bool alreadyLoaded =
false;
60 HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
63 hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
64 if (hModuleSnap == INVALID_HANDLE_VALUE)
65 throw LimaException(
"CreateToolhelp32Snapshoot returned INVALID_HANDLE_VALUE.");
67 me32.dwSize =
sizeof(MODULEENTRY32);
69 if (!Module32First(hModuleSnap, &me32))
71 CloseHandle(hModuleSnap);
78 std::string s(me32.szModule);
82 boost::filesystem::path p(me32.szModule);
83 std::string fn = p.filename().string();
84 if (fn.find(libName, 0) == 0)
90 }
while (Module32Next(hModuleSnap, &me32));
92 CloseHandle(hModuleSnap);
96 std::pair<bool&, const std::string&> data(alreadyLoaded, libName);
98 dl_iterate_phdr([](dl_phdr_info *info,
size_t size,
void* data) ->
int {
102 throw LimaException(
"Callback passed to dl_iterate_phdr unexpectedly got NULL in \"data\" argument.");
104 auto& d = *((std::pair<bool&, const std::string&>*)data);
108 if (info ==
nullptr || info->dlpi_name ==
nullptr)
109 throw LimaException(
"Callback passed to dl_iterate_phdr unexpectedly got NULL in \"info\" argument.");
111 std::string s(info->dlpi_name);
115 boost::filesystem::path p(info->dlpi_name);
116 std::string fn = p.filename().string();
117 if (fn.find(d.second, 0) == 3)
127 return alreadyLoaded;
130DynamicLibrariesManager::DynamicLibrariesManager() :
131 m_d(new DynamicLibrariesManagerPrivate())
141 m_d->isSomethingSimilarLoaded(libName);
142 auto it = m_d->m_handles.find(libName);
143 return (it != m_d->m_handles.end());
149 LDEBUG <<
"DynamicLibrariesManager::loadLibrary() -- libName=" << libName;
151 if (m_d->isSomethingSimilarLoaded(libName))
153 LTRACE <<
"DynamicLibrariesManager::loadLibrary trying to reload dynamic library " << libName;
154 LTRACE <<
"DynamicLibrariesManager::loadLibrary this is not an error, silently ignoring.";
158 auto it = m_d->m_handles.find(libName);
159 if (it != m_d->m_handles.end())
161 LTRACE <<
"DynamicLibrariesManager::loadLibrary trying to reload dynamic library." << libName;
162 LTRACE <<
"DynamicLibrariesManager::loadLibrary this is not an error, silently ignoring.";
166 std::shared_ptr< QLibrary > libhandle;
167 std::vector< std::pair< std::string, std::string> > triedPaths;
169 for (
const auto& path: m_d->m_supplementarySearchPath)
171 LDEBUG <<
"Trying supplementary " << (path+
"/"+libName).c_str();
172 libhandle = std::make_shared<QLibrary>((path+
"/"+libName).c_str());
174 libhandle->setLoadHints(QLibrary::ResolveAllSymbolsHint
175 | QLibrary::ExportExternalSymbolsHint);
176 if (libhandle->load())
178 m_d->m_handles.insert(std::make_pair(libName,libhandle));
179 LDEBUG <<
"the library " << libName.c_str()
180 <<
" was loaded from supplementary search path";
181 LDEBUG <<
"the library fully-qualified name: " << libhandle->fileName();
187 LDEBUG <<
"DynamicLibrariesManager::loadLibrary() -- "
188 <<
"Failed to open supplementary lib " << libhandle->errorString();
189 triedPaths.emplace_back( path, libhandle->errorString().toStdString() );
197 LDEBUG <<
"Trying " << libName;
198 libhandle = std::make_shared<QLibrary>( libName.c_str() );
199 libhandle->setLoadHints(QLibrary::ResolveAllSymbolsHint
200 | QLibrary::ExportExternalSymbolsHint);
201 if (libhandle->load())
203 m_d->m_handles.insert(std::make_pair(libName,libhandle));
204 LDEBUG <<
"the library " << libName
205 <<
" was loaded from system default search path";
206 LDEBUG <<
"the library fully-qualified name: " << libhandle->fileName();
212 for (
const auto& pathErr: triedPaths)
214 LERROR <<
"Failed to load library " << libName <<
"from " << pathErr.first <<
" due to " << pathErr.second;
216 LERROR <<
"Failed to load library " << libName <<
"also from system paths";
217 LERROR <<
"DynamicLibrariesManager::loadLibrary() -- "
218 <<
"Failed to open system lib " << libhandle->errorString();
224 m_d->m_handles[libName] = libhandle;
225 LDEBUG <<
"the library " << libName <<
" was loaded";
233 m_d->m_supplementarySearchPath.begin(),
234 m_d->m_supplementarySearchPath.end(), searchPath)
235 != m_d->m_supplementarySearchPath.end())
241 LINFO <<
"adding search path '" << searchPath.c_str() <<
"'";
244 m_d->m_supplementarySearchPath.push_back(searchPath);
254#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
255 auto list = searchPathes.replace(
"\\",
"/").split(QRegularExpression(
"[;]"),
256 QString::SkipEmptyParts);
258 auto list = searchPathes.replace(
"\\",
"/").split(QRegularExpression(
"[;]"),
262#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
263 auto list = searchPathes.replace(
"\\",
"/").split(QRegularExpression(
"[:;]"),
264 QString::SkipEmptyParts);
266 auto list = searchPathes.replace(
"\\",
"/").split(QRegularExpression(
"[:;]"),
271 for(
const auto& searchPath: list)
274 LINFO <<
"DynamicLibrariesManager::addSearchPathes() adding:" << searchPath;