libmoost
/home/mhx/git/github/libmoost/src/pdl/dynamic_library.cpp
Go to the documentation of this file.
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 }}