pion-net  4.0.9
PionPlugin.hpp
1 // -----------------------------------------------------------------------
2 // pion-common: a collection of common libraries used by the Pion Platform
3 // -----------------------------------------------------------------------
4 // Copyright (C) 2007-2008 Atomic Labs, Inc. (http://www.atomiclabs.com)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #ifndef __PION_PIONPLUGIN_HEADER__
11 #define __PION_PIONPLUGIN_HEADER__
12 
13 #include <vector>
14 #include <string>
15 #include <map>
16 #include <list>
17 #include <boost/thread/mutex.hpp>
18 #include <boost/filesystem/path.hpp>
19 #include <pion/PionConfig.hpp>
20 #include <pion/PionException.hpp>
21 
22 
23 namespace pion { // begin namespace pion
24 
28 class PION_COMMON_API PionPlugin {
29 public:
30 
32  class PluginUndefinedException : public std::exception {
33  public:
34  virtual const char* what() const throw() {
35  return "Plug-in was not loaded properly";
36  }
37  };
38 
41  public:
42  DirectoryNotFoundException(const std::string& dir)
43  : PionException("Plug-in directory not found: ", dir) {}
44  };
45 
48  public:
49  PluginNotFoundException(const std::string& file)
50  : PionException("Plug-in library not found: ", file) {}
51  };
52 
55  public:
56  OpenPluginException(const std::string& file)
57  : PionException("Unable to open plug-in library: ", file) {}
58  };
59 
62  public:
63  PluginMissingCreateException(const std::string& file)
64  : PionException("Plug-in library does not include create() symbol: ", file) {}
65  };
66 
69  public:
70  PluginMissingDestroyException(const std::string& file)
71  : PionException("Plug-in library does not include destroy() symbol: ", file) {}
72  };
73 
81  static inline bool findPluginFile(std::string& path_to_file,
82  const std::string& name)
83  {
84  return findFile(path_to_file, name, PION_PLUGIN_EXTENSION);
85  }
86 
94  static inline bool findConfigFile(std::string& path_to_file,
95  const std::string& name)
96  {
97  return findFile(path_to_file, name, PION_CONFIG_EXTENSION);
98  }
99 
107  static bool findStaticEntryPoint(const std::string& plugin_name,
108  void **create_func,
109  void **destroy_func);
110 
118  static void addStaticEntryPoint(const std::string& plugin_name,
119  void *create_func,
120  void *destroy_func);
121 
130  static void checkCygwinPath(boost::filesystem::path& final_path,
131  const std::string& path_string);
132 
134  static void addPluginDirectory(const std::string& dir);
135 
137  static void resetPluginDirectories(void);
138 
139 
140  // default destructor
141  virtual ~PionPlugin() { releaseData(); }
142 
144  inline bool is_open(void) const { return (m_plugin_data != NULL); }
145 
147  inline std::string getPluginName(void) const {
148  return (is_open() ? m_plugin_data->m_plugin_name : std::string());
149  }
150 
152  static void getAllPluginNames(std::vector<std::string>& plugin_names);
153 
166  void open(const std::string& plugin_name);
167 
180  void openFile(const std::string& plugin_file);
181 
190  void openStaticLinked(const std::string& plugin_name,
191  void *create_func,
192  void *destroy_func);
193 
195  inline void close(void) { releaseData(); }
196 
197 protected:
198 
203  {
206  : m_lib_handle(NULL), m_create_func(NULL), m_destroy_func(NULL),
207  m_references(0)
208  {}
209  PionPluginData(const std::string& plugin_name)
210  : m_lib_handle(NULL), m_create_func(NULL), m_destroy_func(NULL),
211  m_plugin_name(plugin_name), m_references(0)
212  {}
213  PionPluginData(const PionPluginData& p)
214  : m_lib_handle(p.m_lib_handle), m_create_func(p.m_create_func),
215  m_destroy_func(p.m_destroy_func), m_plugin_name(p.m_plugin_name),
216  m_references(p.m_references)
217  {}
218 
220  void * m_lib_handle;
221 
224 
227 
229  std::string m_plugin_name;
230 
232  unsigned long m_references;
233  };
234 
235 
237  PionPlugin(void) : m_plugin_data(NULL) {}
238 
240  PionPlugin(const PionPlugin& p) : m_plugin_data(NULL) { grabData(p); }
241 
243  PionPlugin& operator=(const PionPlugin& p) { grabData(p); return *this; }
244 
246  inline void *getCreateFunction(void) {
247  return (is_open() ? m_plugin_data->m_create_func : NULL);
248  }
249 
251  inline void *getDestroyFunction(void) {
252  return (is_open() ? m_plugin_data->m_destroy_func : NULL);
253  }
254 
256  void releaseData(void);
257 
259  void grabData(const PionPlugin& p);
260 
261 
262 private:
263 
265  class StaticEntryPoint
266  {
267  public:
268  StaticEntryPoint(const std::string& name, void *create, void *destroy)
269  : m_plugin_name(name), m_create_func(create), m_destroy_func(destroy)
270  {}
271  std::string m_plugin_name;
272  void * m_create_func;
273  void * m_destroy_func;
274  };
275 
277  typedef std::list<StaticEntryPoint> StaticEntryPointList;
278 
280  typedef std::map<std::string, PionPluginData*> PluginMap;
281 
282 
292  static bool findFile(std::string& path_to_file, const std::string& name,
293  const std::string& extension);
294 
305  static bool checkForFile(std::string& final_path, const std::string& start_path,
306  const std::string& name, const std::string& extension);
307 
314  static void openPlugin(const std::string& plugin_file,
315  PionPluginData& plugin_data);
316 
318  static std::string getPluginName(const std::string& plugin_file);
319 
321  static void *loadDynamicLibrary(const std::string& plugin_file);
322 
324  static void closeDynamicLibrary(void *lib_handle);
325 
327  static void *getLibrarySymbol(void *lib_handle, const std::string& symbol);
328 
329 
331  static const std::string PION_PLUGIN_CREATE;
332 
334  static const std::string PION_PLUGIN_DESTROY;
335 
337  static const std::string PION_PLUGIN_EXTENSION;
338 
340  static const std::string PION_CONFIG_EXTENSION;
341 
343  static std::vector<std::string> m_plugin_dirs;
344 
346  static PluginMap m_plugin_map;
347 
349  static boost::mutex m_plugin_mutex;
350 
352  static StaticEntryPointList *m_entry_points_ptr;
353 
355  PionPluginData * m_plugin_data;
356 };
357 
358 
363 template <typename InterfaceClassType>
365  public PionPlugin
366 {
367 protected:
368 
370  typedef InterfaceClassType* CreateObjectFunction(void);
371 
373  typedef void DestroyObjectFunction(InterfaceClassType*);
374 
375 
376 public:
377 
380  virtual ~PionPluginPtr() {}
381 
384 
386  PionPluginPtr& operator=(const PionPluginPtr& p) { grabData(p); return *this; }
387 
389  inline InterfaceClassType *create(void) {
390  CreateObjectFunction *create_func =
392  if (create_func == NULL)
393  throw PluginUndefinedException();
394  return create_func();
395  }
396 
398  inline void destroy(InterfaceClassType *object_ptr) {
399  DestroyObjectFunction *destroy_func =
401  if (destroy_func == NULL)
402  throw PluginUndefinedException();
403  destroy_func(object_ptr);
404  }
405 };
406 
407 
421 #ifdef PION_STATIC_LINKING
422 
423 #define PION_DECLARE_PLUGIN(plugin_name) \
424  class plugin_name; \
425  extern "C" plugin_name *pion_create_##plugin_name(void); \
426  extern "C" void pion_destroy_##plugin_name(plugin_name *plugin_ptr); \
427  static pion::StaticEntryPointHelper helper_##plugin_name(#plugin_name, pion_create_##plugin_name, pion_destroy_##plugin_name);
428 
430 class StaticEntryPointHelper {
431 public:
432  StaticEntryPointHelper(const std::string& name, void *create, void *destroy)
433  {
434  pion::PionPlugin::addStaticEntryPoint(name, create, destroy);
435  }
436 };
437 
438 #else
439 
440 #define PION_DECLARE_PLUGIN(plugin_name)
441 
442 #endif
443 
444 } // end namespace pion
445 
446 #endif
void * getCreateFunction(void)
returns a pointer to the plug-in&#39;s &quot;create object&quot; function
Definition: PionPlugin.hpp:246
PionPluginPtr & operator=(const PionPluginPtr &p)
assignment operator
Definition: PionPlugin.hpp:386
PionPlugin(void)
default constructor is private (use PionPluginPtr class to create objects)
Definition: PionPlugin.hpp:237
exception thrown if the plug-in directory does not exist
Definition: PionPlugin.hpp:40
void * m_lib_handle
symbol library loaded from a shared object file
Definition: PionPlugin.hpp:220
exception thrown if the plug-in file cannot be opened
Definition: PionPlugin.hpp:54
InterfaceClassType * CreateObjectFunction(void)
data type for a function that is used to create object instances
Definition: PionPlugin.hpp:370
void * m_create_func
function used to create instances of the plug-in object
Definition: PionPlugin.hpp:223
std::string getPluginName(void) const
returns the name of the plugin that is currently open
Definition: PionPlugin.hpp:147
PionPluginData(void)
default constructors for convenience
Definition: PionPlugin.hpp:205
void DestroyObjectFunction(InterfaceClassType *)
data type for a function that is used to destroy object instances
Definition: PionPlugin.hpp:373
void close(void)
closes plug-in library
Definition: PionPlugin.hpp:195
void grabData(const PionPlugin &p)
grabs a reference to another plug-in&#39;s shared library symbols
Definition: PionPlugin.cpp:161
PionPluginPtr(const PionPluginPtr &p)
copy constructor
Definition: PionPlugin.hpp:383
PionPlugin(const PionPlugin &p)
copy constructor
Definition: PionPlugin.hpp:240
bool is_open(void) const
returns true if a shared library is loaded/open
Definition: PionPlugin.hpp:144
static bool findPluginFile(std::string &path_to_file, const std::string &name)
Definition: PionPlugin.hpp:81
PionPlugin & operator=(const PionPlugin &p)
assignment operator
Definition: PionPlugin.hpp:243
static void addStaticEntryPoint(const std::string &plugin_name, void *create_func, void *destroy_func)
Definition: PionPlugin.cpp:367
exception thrown if the plug-in file cannot be found
Definition: PionPlugin.hpp:47
exception thrown if the plug-in file cannot be opened
Definition: PionPlugin.hpp:32
PionPluginPtr(void)
default constructor &amp; destructor
Definition: PionPlugin.hpp:379
void destroy(InterfaceClassType *object_ptr)
destroys an instance of the plug-in object
Definition: PionPlugin.hpp:398
InterfaceClassType * create(void)
creates a new instance of the plug-in object
Definition: PionPlugin.hpp:389
void * m_destroy_func
function used to destroy instances of the plug-in object
Definition: PionPlugin.hpp:226
exception thrown if a plug-in library is missing the destroy() function
Definition: PionPlugin.hpp:68
void * getDestroyFunction(void)
returns a pointer to the plug-in&#39;s &quot;destroy object&quot; function
Definition: PionPlugin.hpp:251
exception thrown if a plug-in library is missing the create() function
Definition: PionPlugin.hpp:61
unsigned long m_references
number of references to this class
Definition: PionPlugin.hpp:232
static bool findConfigFile(std::string &path_to_file, const std::string &name)
Definition: PionPlugin.hpp:94
std::string m_plugin_name
the name of the plugin (must be unique per process)
Definition: PionPlugin.hpp:229