36 #if defined(__linux__) or defined(__APPLE__) 42 #include <boost/format.hpp> 44 #include "../logging/Logger.h" 45 #include "../logging/LoggerFactory.h" 49 using namespace boost;
59 Impl(
const std::string& name,
60 const std::string& library)
61 : logger(logging::LoggerFactory::getInstance()
62 .
getLogger(str((format(
"rsc.plugins.Plugin[%1%]")
64 name(name), library(library),
65 loaded(false), handle(NULL),
66 init(NULL), shutdown(NULL) {
77 void load(
bool wrapExceptions) {
83 "Plugin %1% is already loaded. Cannot load it again,")
87 RSCINFO(this->logger,
"Trying to load library `" << this->library <<
"'");
94 =
reinterpret_cast<InitFunction
>(resolveSymbol(PLUGIN_INIT_SYMBOL));
96 =
reinterpret_cast<ShutdownFunction
>(resolveSymbol(PLUGIN_SHUTDOWN_SYMBOL));
99 RSCINFO(this->logger,
"Initializing");
100 if (wrapExceptions) {
104 }
catch (
const std::exception& e) {
105 throw runtime_error(str(format(
"Plugin `%1%' failed to initialize: %2%")
109 throw runtime_error(str(format(
"Plugin `%1%' failed to initialize due to unknown error.")
122 str(format(
"Plugin `%1%' failed cannot be unloaded because it has not been loaded correctly.")
127 RSCINFO(this->logger,
"Shutting down");
128 this->loaded =
false;
130 if (wrapExceptions) {
133 }
catch (
const std::exception& e) {
134 throw runtime_error(str(format(
"Plugin `%1%' failed to shutdown: %2%")
138 throw runtime_error(str(format(
"Plugin `%1%' failed to shutdown due to unknown error.")
146 typedef void (*InitFunction)();
147 typedef void (*ShutdownFunction)();
165 #if defined(__linux__) || defined(__APPLE__) 166 if (!(this->handle = dlopen(this->library.c_str(), RTLD_NOW))) {
167 const char* result = dlerror();
168 throw runtime_error(str(format(
"Failed to load plugin `%1%' from shared object `%2%': %3%.")
169 % this->name % this->library
170 % (result ? result :
"<unknown error>")));
172 #elif defined(_WIN32) 173 if (!(this->handle= LoadLibrary(this->library.c_str()))) {
174 throw runtime_error(str(format(
"Failed to load plugin `%1%' from shared object `%2%': %3%.")
175 % this->name % this->library % GetLastError()));
178 throw runtime_error(
"Plugins are not implemented for this platform.");
183 RSCINFO(this->logger,
"Resolving symbol `" 184 << name <<
"' in library `" << this->library <<
"'");
186 assert(this->handle);
189 #if defined(__linux__) || defined(__APPLE__) 190 if (!(address = dlsym(this->handle, name.c_str()))) {
191 const char* result = dlerror();
192 throw runtime_error(str(format(
"Plugin `%1%' failed to define function `%2%': %3%")
194 % (result ? result :
"<unknown error>")));
196 #elif defined(_WIN32) 197 if (!(address = reinterpret_cast<void*>(GetProcAddress(this->handle, name.c_str())))) {
198 throw runtime_error(str(format(
"Plugin `%1%' failed to define function `%2%': %3%")
199 % this->name % name % GetLastError()));
202 throw runtime_error(
"Plugins are not implemented for this platform.");
216 return this->
impl->getName();
220 this->
impl->load(wrapExceptions);
224 this->
impl->unload(wrapExceptions);
228 return this->
impl->getLibrary();
void unload(bool wrapExceptions)
const std::string & getName() const
Returns the name of the plugin.
const string & getName() const
Impl(const std::string &name, const std::string &library)
const std::string PLUGIN_INIT_SYMBOL
void load(bool wrapExceptions)
void * resolveSymbol(const string &name)
std::string getLibrary() const
Returns the path to the library implementing this plugin.
rsc::logging::LoggerPtr logger
static boost::shared_ptr< Plugin > create(const std::string &name, const std::string &library)
#define RSCINFO(logger, msg)
const std::string PLUGIN_SHUTDOWN_SYMBOL
void load(bool wrapExceptions=true)
Tries to load the functionality of the plugin into the current process.
ShutdownFunction shutdown
boost::shared_ptr< Plugin > PluginPtr
void unload(bool wrapExceptions=true)
Tries to unload the functionality of the plugin.
boost::scoped_ptr< Impl > impl
const string & getLibrary() const
boost::shared_ptr< Logger > LoggerPtr