RobotTestingFramework 2.0.1
Robot Testing Framework
Loading...
Searching...
No Matches
DllPluginLoader_impl.h
Go to the documentation of this file.
1/*
2 * Robot Testing Framework
3 *
4 * Copyright (C) 2015-2019 Istituto Italiano di Tecnologia (IIT)
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21
22#ifndef ROBOTTESTINGFRAMEWORK_DLLPLUGINLOADERIMPL_H
23#define ROBOTTESTINGFRAMEWORK_DLLPLUGINLOADERIMPL_H
24
28
29#include <string>
30
34template <class T>
36{
37
44
45public:
50 plugin(nullptr)
51 {
52 }
53
58 {
59 close();
60 }
61
62
69 T* open(const std::string filename,
70 const std::string factory_name)
71 {
72
73 // close any previous loaded plugin
74 close();
75
76 // create an instance of plugin class and factory
78
79 // load the test case plugin
80 open_internal(filename, factory_name);
81
82 if (!plugin->factory.isValid()) {
83 if (plugin->factory.getStatus() == shlibpp::VOCAB('f', 'a', 'c', 't')) {
84 std::string plug_type = (factory_name == ROBOTTESTINGFRAMEWORK_PLUGIN_FACTORY_NAME) ? "test case" : "fixture manager";
85 error = "cannot load plugin " + filename + "; (it is not a Robot Testing Framework " + plug_type + " plugin!)";
86 } else {
87 error = "cannot load plugin " + filename + "; error (" + shlibpp::Vocab::decode(plugin->factory.getStatus()) + ") : " + plugin->factory.getError();
88 }
89 delete plugin;
90 plugin = nullptr;
91 return nullptr;
92 }
93
94 // TODO: check if this is neccessary!!!
95 //plugin->factory.addRef();
96
97 // create an instance of the test case from the plugin
98 plugin->test.open(plugin->factory);
99 if (!plugin->test.isValid()) {
100 //error = Asserter::format("cannot create an instance of TestCase from %s", filename.c_str());
101 delete plugin;
102 plugin = nullptr;
103 return nullptr;
104 }
105
106 return &plugin->test.getContent();
107 }
108
109
114 void close()
115 {
116 if (plugin)
117 delete plugin;
118 plugin = nullptr;
119 error.clear();
120 }
121
126 const std::string& getLastError()
127 {
128 return error;
129 }
130
131private:
132 std::string error;
134
135 void open_internal(const std::string filename,
136 const std::string factory_name)
137 {
138
139 std::string fullpath;
140#if defined(_WIN32)
141 std::string ext = ".dll";
142#else
143 std::string ext = ".so";
144#endif
145 std::string basename;
146 bool has_ext;
147 if (filename.find(ext) != std::string::npos) {
148 basename = filename.substr(0, filename.size() - ext.size());
149 has_ext = true;
150 } else {
151 basename = filename;
152 has_ext = false;
153 }
154
155#if defined(_MSC_VER) && !defined(NDEBUG)
156 // MSVC DEBUG build: try debug name before basic name
157 if (!has_ext) {
158 fullpath = basename + "d" + ext;
159 if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
160 return;
161 }
162#endif
163
164 // Basic name
165 fullpath = basename + ext;
166 if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
167 return;
168
169#if defined(_MSC_VER) && defined(NDEBUG)
170 // MSVC RELEASE build: try debug name after basic name
171 if (!has_ext) {
172 fullpath = basename + "d" + ext;
173 if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
174 return;
175 }
176#endif
177
178
179#ifdef CMAKE_INTDIR
180 // On multi-config system, try to find the plugin in the
181 // current config subdirectory
182
183# if defined(_MSC_VER) && !defined(NDEBUG)
184 // MSVC DEBUG build: try debug name before basic name
185 if (!has_ext) {
186 fullpath = std::string(CMAKE_INTDIR) + "/" + basename + "d" + ext;
187 if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
188 return;
189 }
190# endif
191
192 // Basic name
193 fullpath = std::string(CMAKE_INTDIR) + "/" + basename + ext;
194 if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
195 return;
196
197# if defined(_MSC_VER) && defined(NDEBUG)
198 // MSVC RELEASE build: try debug name after basic name
199 if (!has_ext) {
200 fullpath = std::string(CMAKE_INTDIR) + "/" + basename + "d" + ext;
201 if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
202 return;
203 }
204# endif
205
206#endif
207 }
208};
209
210#endif // ROBOTTESTINGFRAMEWORK_DLLPLUGINLOADERIMPL_H
#define ROBOTTESTINGFRAMEWORK_PLUGIN_FACTORY_NAME
Definition Plugin.h:27
shlibpp::SharedLibraryClassFactory< T > factory
shlibpp::SharedLibraryClass< T > test
class DllPluginLoaderImpl
T * open(const std::string filename, const std::string factory_name)
open Loads a generic plugin
void open_internal(const std::string filename, const std::string factory_name)
const std::string & getLastError()
getLastError gets the last error if any.
DllPluginLoaderImpl()
DllPluginLoaderImpl constructor.
void close()
close Unloads the plugin and deletes any allocated memory.
virtual ~DllPluginLoaderImpl()
DllPluginLoaderImpl destructor.
A type-safe wrapper for SharedLibraryFactory, committing to creation/destruction of instances of a pa...
Container for an object created using a factory provided by a shared library.
static std::string decode(int code)
Definition Vocab.h:63
constexpr int32_t VOCAB(char a, char b=0, char c=0, char d=0)
Definition Vocab.h:31