libmoost
|
00001 /* vim:set ts=3 sw=3 sts=3 et: */ 00028 #include "../../include/moost/pdl/platform.h" 00029 #include "../../include/moost/pdl/dynamic_library.h" 00030 #include "../../include/moost/pdl/dynamic_class.h" 00031 #include "../../include/moost/pdl/exception.h" 00032 00033 #include "dynamic_library_if.hpp" 00034 00035 #if PLATFORM_WIN32 00036 # include "impl/dl_win32.ipp" 00037 #elif PDL_PLATFORM_POSIX 00038 # include "impl/dl_posix.ipp" 00039 #endif 00040 00041 extern "C" void *(*moost_pdl_symbol_to_function_cast_(void *p))(); 00042 00043 namespace moost { namespace pdl { 00044 00045 dynamic_library::dynamic_library() 00046 { 00047 } 00048 00049 dynamic_library::dynamic_library(const std::string& library_name, bool resolve_symbols) 00050 { 00051 open(library_name, resolve_symbols); 00052 } 00053 00054 void dynamic_library::open(const std::string& library_name, bool resolve_symbols) 00055 { 00056 m_impl.reset(new dynamic_library_impl(library_name, resolve_symbols)); 00057 } 00058 00059 void dynamic_library::close() 00060 { 00061 m_impl.reset(); 00062 } 00063 00064 dynamic_class *dynamic_library::create_instance(const std::string& class_name) 00065 { 00066 typedef dynamic_class *(*factory_t)(); 00067 00068 if (!is_open()) 00069 { 00070 throw exception("no library loaded"); 00071 } 00072 00073 const std::string factory_name(std::string("PDL_create_") + std::string(class_name)); 00074 00075 void *symbol = m_impl->get_symbol_by_name(factory_name); 00076 void *(*function)() = moost_pdl_symbol_to_function_cast_(symbol); 00077 factory_t factory = reinterpret_cast<factory_t>(function); 00078 00079 if (!factory) 00080 { 00081 throw class_not_found_error("class " + class_name + " not found in " + m_impl->library_path()); 00082 } 00083 00084 dynamic_class *instance = factory(); 00085 00086 if (!instance) 00087 { 00088 throw exception("failed to create instance of class " + class_name); 00089 } 00090 00091 instance->m_library = m_impl; 00092 00093 return instance; 00094 } 00095 00096 void dynamic_library::dynamic_class_deleter(dynamic_class *p) 00097 { 00098 try 00099 { 00100 // Temporarily save the library pointer to avoid unloading the shared 00101 // object before destruction of the instances is finished. 00102 00103 boost::shared_ptr<dynamic_library_if> dl = p->m_library; 00104 00105 delete p; 00106 } 00107 catch (...) 00108 { 00109 } 00110 } 00111 00112 }}