Tesseract
Motion Planning Environment
Loading...
Searching...
No Matches
class_loader.hpp
Go to the documentation of this file.
1
26#ifndef TESSERACT_COMMON_CLASS_LOADER_HPP
27#define TESSERACT_COMMON_CLASS_LOADER_HPP
28
31#include <boost/config.hpp>
32#include <boost/dll/import.hpp>
33#include <boost/dll/alias.hpp>
34#include <boost/dll/import_class.hpp>
35#include <boost/dll/shared_library.hpp>
36#include <boost/dll/runtime_symbol_info.hpp>
37#include <console_bridge/console.h>
39
41
42namespace tesseract_common
43{
44template <class ClassBase>
45std::shared_ptr<ClassBase> ClassLoader::createSharedInstance(const std::string& symbol_name,
46 const std::string& library_name,
47 const std::string& library_directory)
48{
49 boost::system::error_code ec;
50 boost::dll::shared_library lib;
51 if (library_directory.empty())
52 {
53 boost::filesystem::path sl(library_name);
54 boost::dll::load_mode::type mode =
55 boost::dll::load_mode::append_decorations | boost::dll::load_mode::search_system_folders;
56 lib = boost::dll::shared_library(sl, ec, mode);
57 }
58 else
59 {
60 boost::filesystem::path sl = boost::filesystem::path(library_directory) / library_name;
61 lib = boost::dll::shared_library(sl, ec, boost::dll::load_mode::append_decorations);
62 }
63
64 // Check if it failed to find or load library
65 if (ec)
66 throw std::runtime_error("Failed to find or load library: " + decorate(library_name, library_directory) +
67 " with error: " + ec.message());
68
69 // Check if library has symbol
70 if (!lib.has(symbol_name))
71 throw std::runtime_error("Failed to find symbol '" + symbol_name +
72 "' in library: " + decorate(library_name, library_directory));
73
74#if BOOST_VERSION >= 107600
75 boost::shared_ptr<ClassBase> plugin = boost::dll::import_symbol<ClassBase>(lib, symbol_name);
76#else
77 boost::shared_ptr<ClassBase> plugin = boost::dll::import<ClassBase>(lib, symbol_name);
78#endif
79 return std::shared_ptr<ClassBase>(plugin.get(), [plugin](ClassBase*) mutable { plugin.reset(); });
80}
81
83 const std::string& library_name,
84 const std::string& library_directory)
85{
86 boost::system::error_code ec;
87 boost::dll::shared_library lib;
88 if (library_directory.empty())
89 {
90 boost::filesystem::path sl(library_name);
91 boost::dll::load_mode::type mode =
92 boost::dll::load_mode::append_decorations | boost::dll::load_mode::search_system_folders;
93 lib = boost::dll::shared_library(sl, ec, mode);
94 }
95 else
96 {
97 boost::filesystem::path sl = boost::filesystem::path(library_directory) / library_name;
98 lib = boost::dll::shared_library(sl, ec, boost::dll::load_mode::append_decorations);
99 }
100
101 // Check if it failed to find or load library
102 if (ec)
103 {
104 CONSOLE_BRIDGE_logDebug("Failed to find or load library: %s with error: %s",
105 decorate(library_name, library_directory).c_str(),
106 ec.message().c_str());
107 return false;
108 }
109
110 return lib.has(symbol_name);
111}
112
113std::vector<std::string> ClassLoader::getAvailableSymbols(const std::string& section,
114 const std::string& library_name,
115 const std::string& library_directory)
116{
117 boost::system::error_code ec;
118 boost::dll::shared_library lib;
119 if (library_directory.empty())
120 {
121 boost::filesystem::path sl(library_name);
122 boost::dll::load_mode::type mode =
123 boost::dll::load_mode::append_decorations | boost::dll::load_mode::search_system_folders;
124 lib = boost::dll::shared_library(sl, ec, mode);
125 }
126 else
127 {
128 boost::filesystem::path sl = boost::filesystem::path(library_directory) / library_name;
129 lib = boost::dll::shared_library(sl, ec, boost::dll::load_mode::append_decorations);
130 }
131
132 // Check if it failed to find or load library
133 if (ec)
134 {
135 CONSOLE_BRIDGE_logDebug("Failed to find or load library: %s with error: %s",
136 decorate(library_name, library_directory).c_str(),
137 ec.message().c_str());
138 return {};
139 }
140
141 // Class `library_info` can extract information from a library
142 boost::dll::library_info inf(lib.location());
143
144 // Getting symbols exported from he provided section
145 return inf.symbols(section);
146}
147
148std::vector<std::string> ClassLoader::getAvailableSections(const std::string& library_name,
149 const std::string& library_directory,
150 bool include_hidden)
151{
152 boost::system::error_code ec;
153 boost::dll::shared_library lib;
154 if (library_directory.empty())
155 {
156 boost::filesystem::path sl(library_name);
157 boost::dll::load_mode::type mode =
158 boost::dll::load_mode::append_decorations | boost::dll::load_mode::search_system_folders;
159 lib = boost::dll::shared_library(sl, ec, mode);
160 }
161 else
162 {
163 boost::filesystem::path sl = boost::filesystem::path(library_directory) / library_name;
164 lib = boost::dll::shared_library(sl, ec, boost::dll::load_mode::append_decorations);
165 }
166
167 // Check if it failed to find or load library
168 if (ec)
169 {
170 CONSOLE_BRIDGE_logDebug("Failed to find or load library: %s with error: %s",
171 decorate(library_name, library_directory).c_str(),
172 ec.message().c_str());
173 return {};
174 }
175
176 // Class `library_info` can extract information from a library
177 boost::dll::library_info inf(lib.location());
178
179 // Getting section from library
180 std::vector<std::string> sections = inf.sections();
181
182 auto search_fn = [include_hidden](const std::string& section) {
183 if (section.empty())
184 return true;
185
186 if (include_hidden)
187 return false;
188
189 return (section.substr(0, 1) == ".");
190 };
191
192 sections.erase(std::remove_if(sections.begin(), sections.end(), search_fn), sections.end());
193 return sections;
194}
195
196std::string ClassLoader::decorate(const std::string& library_name, const std::string& library_directory)
197{
198 boost::filesystem::path sl;
199 if (library_directory.empty())
200 sl = boost::filesystem::path(library_name);
201 else
202 sl = boost::filesystem::path(library_directory) / library_name;
203
204 boost::filesystem::path actual_path =
205 (std::strncmp(sl.filename().string().c_str(), "lib", 3) != 0 ?
206 boost::filesystem::path((sl.has_parent_path() ? sl.parent_path() / L"lib" : L"lib").native() +
207 sl.filename().native()) :
208 sl);
209
210 actual_path += boost::dll::shared_library::suffix();
211 return actual_path.string();
212}
213
214} // namespace tesseract_common
215
216#endif // TESSERACT_COMMON_CLASS_LOADER_HPP
Class Loader to be used throughout Tesseract for loading plugins.
Common Tesseract Macros.
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
Definition: macros.h:71
Definition: create_convex_hull.cpp:36
Definition: allowed_collision_matrix.h:16
const std::string symbol_name
Definition: plugin_loader_unit.cpp:58
sections
Definition: plugin_loader_unit.cpp:65
auto plugin
Definition: plugin_loader_unit.cpp:77
static bool isClassAvailable(const std::string &symbol_name, const std::string &library_name, const std::string &library_directory="")
Check if the symbol is available in the library_name searching system folders for library.
Definition: class_loader.hpp:82
static std::vector< std::string > getAvailableSections(const std::string &library_name, const std::string &library_directory="", bool include_hidden=false)
Get a list of available sections.
Definition: class_loader.hpp:148
static std::vector< std::string > getAvailableSymbols(const std::string &section, const std::string &library_name, const std::string &library_directory="")
Get a list of available symbols under the provided section.
Definition: class_loader.hpp:113
static std::shared_ptr< ClassBase > createSharedInstance(const std::string &symbol_name, const std::string &library_name, const std::string &library_directory="")
Create a shared instance for the provided symbol_name loaded from the library_name searching system f...
Definition: class_loader.hpp:45
static std::string decorate(const std::string &library_name, const std::string &library_directory="")
Give library name without prefix and suffix it will return the library name with the prefix and suffi...
Definition: class_loader.hpp:196