40 #ifndef __OPENFLUID_MACHINE_WAREPLUGINSMANAGER_HPP__
41 #define __OPENFLUID_MACHINE_WAREPLUGINSMANAGER_HPP__
58 #include <openfluid/config.hpp>
64 typedef std::string* (*GetWareABIVersionProc)();
66 typedef std::string* (*GetWareLinkUIDProc)();
80 template<
class SignatureInstanceType,
class ItemInstanceType,
typename SignatureProc,
typename BodyProc>
91 QLibrary* loadPluginLibrary(
const std::string& FullFilePath)
93 std::string PluginFileName = QFileInfo(QString::fromStdString(FullFilePath)).fileName().toStdString();
95 if (m_LoadedPluginsLibraries.find(PluginFileName) == m_LoadedPluginsLibraries.end())
97 m_LoadedPluginsLibraries[PluginFileName] = std::make_unique<QLibrary>(QString::fromStdString(FullFilePath));
100 return m_LoadedPluginsLibraries[PluginFileName].get();
108 ItemInstanceType* buildWareContainerWithSignatureOnly(
const std::string& ID,
bool StrictABICheck =
true)
110 std::string PluginFilename = ID+getPluginFilenameSuffix()+openfluid::config::PLUGINS_EXT;
111 std::string PluginFullPath = getPluginFullPath(PluginFilename);
112 ItemInstanceType* WareItem =
nullptr;
114 QLibrary* PlugLib = loadPluginLibrary(PluginFullPath);
117 if (PlugLib && PlugLib->load())
119 WareItem =
new ItemInstanceType();
120 WareItem->FileFullPath = PluginFullPath;
126 std::unique_ptr<std::string> StrPtr(ABIVersionProc());
132 WareItem->Verified =
false;
136 if (WareItem->Verified)
144 WareItem->Signature = SProc();
146 if (WareItem->Signature ==
nullptr)
149 "Signature from plugin file " + PluginFilename +
150 " cannot be instanciated");
153 WareItem->Verified = (WareItem->Signature->ID == ID);
161 std::unique_ptr<std::string> StrPtr(LinkUIDProc());
162 WareItem->LinkUID = *StrPtr;
168 "Format error in plugin file " + PluginFilename);
174 "Compatibility version mismatch for plugin file " + PluginFilename);
180 "Unable to load plugin from file " + PluginFilename);
191 SignatureInstanceType* getWareSignature(
const std::string& PluginFilename,
bool StrictABICheck =
true)
193 std::string PluginFullPath = getPluginFullPath(PluginFilename);
194 SignatureInstanceType* Sign =
nullptr;
198 .
addInfos({{
"pluginfullpath",PluginFullPath},{
"pluginfilename",PluginFilename}});
201 QLibrary* PlugLib = loadPluginLibrary(PluginFullPath);
208 Sign =
new SignatureInstanceType();
209 Sign->FileFullPath = PluginFullPath;
215 std::unique_ptr<std::string> StrPtr(ABIVersionProc());
221 Sign->Verified =
false;
234 Sign->Signature = SProc();
241 if (Sign->Signature ==
nullptr)
247 QString::fromStdString(PluginFilename).startsWith(QString::fromStdString(Sign->Signature->ID));
253 std::unique_ptr<std::string> StrPtr(LinkUIDProc());
254 Sign->LinkUID = *StrPtr;
317 virtual std::string getPluginFullPath(
const std::string& Filename)
const = 0;
328 virtual std::vector<std::string> getPluginsSearchPaths()
const = 0;
339 virtual std::string getPluginFilenameSuffix()
const = 0;
355 std::vector<std::string> PluginsPaths = getPluginsSearchPaths();
356 std::vector<std::string> PluginFiles;
357 std::vector<std::string> TmpFiles;
361 for (i=0;i<PluginsPaths.size();i++)
364 getPluginFilenameSuffix(),
365 openfluid::config::PLUGINS_EXT,
false,
true);
367 for (j=0;j<TmpFiles.size();j++)
369 PluginFiles.push_back(TmpFiles[j]);
374 SignatureInstanceType* CurrentPlug =
nullptr;
376 for (i=0;i<PluginFiles.size();i++)
380 CurrentPlug = getWareSignature(PluginFiles[i]);
382 if (CurrentPlug && CurrentPlug->Verified)
400 return SearchResults;
415 ItemInstanceType* WareItem = buildWareContainerWithSignatureOnly(ID);
417 if (WareItem !=
nullptr && WareItem->Verified)
436 std::string PluginFullPath = WareItem->FileFullPath;
438 QLibrary* PlugLib = loadPluginLibrary(PluginFullPath);
441 if (PlugLib && PlugLib->load())
448 WareItem->Body.reset(BProc());
450 if (WareItem->Body ==
nullptr)
453 "Ware from plugin file " + PluginFullPath +
454 " cannot be instanciated");
461 "Format error in plugin file " + PluginFullPath);
467 "Unable to find plugin file " + PluginFullPath);
481 for (
auto it=m_LoadedPluginsLibraries.begin();it != m_LoadedPluginsLibraries.end(); ++it)
483 it->second.get()->unload();
486 m_LoadedPluginsLibraries.clear();