X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fstlplus%2Fportability%2Fdynaload.cpp;h=4cd5741d9ad924cac329eb9d082cd902971d09c8;hp=cdd18489adf407660ada8c062909ae41fdc47a8f;hb=5846afb00833cc72fe72422ca896d2387c712cb4;hpb=a97500609dc3c1b11f9786d32bc458eb00de4c36 diff --git a/src/stlplus/portability/dynaload.cpp b/src/stlplus/portability/dynaload.cpp index cdd1848..4cd5741 100644 --- a/src/stlplus/portability/dynaload.cpp +++ b/src/stlplus/portability/dynaload.cpp @@ -1,184 +1,184 @@ -//////////////////////////////////////////////////////////////////////////////// - -// Author: Andy Rushton -// Copyright: (c) Southampton University 1999-2004 -// (c) Andy Rushton 2004-2009 -// License: BSD License, see ../docs/license.html - -//////////////////////////////////////////////////////////////////////////////// -#include "dynaload.hpp" - -#ifdef MSWINDOWS -#include -#else -#include -#endif - -//////////////////////////////////////////////////////////////////////////////// - -#ifdef MSWINDOWS - -static std::string last_error(void) -{ - // get the last error code - if none, return the empty string - DWORD err = GetLastError(); - if (err == 0) return std::string(); - // get the system message for this error code - char* message; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - 0, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&message, - 0,0); - std::string result = message; - LocalFree(message); - // the error message is for some perverse reason newline terminated - remove this - if (result[result.size()-1] == '\n') - result.erase(result.end()-1); - if (result[result.size()-1] == '\r') - result.erase(result.end()-1); - return result; -} - -#else - -static std::string last_error(void) -{ - return std::string(dlerror()); -} - -#endif - -//////////////////////////////////////////////////////////////////////////////// - -namespace stlplus -{ - - //////////////////////////////////////////////////////////////////////////////// - // library management - - // construct the object but do not load - dynaload::dynaload(void) : m_handle(0) - { - } - - // construct and load - dynaload::dynaload(const std::string& library) : m_handle(0) - { - load(library); - } - - // destroy and unload if loaded - dynaload::~dynaload(void) - { - unload(); - } - - // load the library - return success or fail - bool dynaload::load(const std::string& library) - { -#ifdef MSWINDOWS - m_handle = (void*)LoadLibrary(library.c_str()); -#elif defined(CYGWIN) - m_handle = dlopen(library.c_str(),RTLD_NOW); -#else - std::string full_library = std::string("lib") + library + std::string(".so"); - m_handle = dlopen(full_library.c_str(),RTLD_NOW); -#endif - if (!m_handle) - { - m_error = load_error; - m_text = last_error(); - } - return loaded(); - } - - // unload the library if loaded - bool dynaload::unload(void) - { - if (!loaded()) return false; -#ifdef MSWINDOWS - int status = FreeLibrary((HINSTANCE)m_handle) ? 0 : 1; -#else - int status = dlclose(m_handle); -#endif - if (status != 0) - { - m_error = unload_error; - m_text = last_error(); - } - return status == 0; - } - - // test whether the library is loaded - bool dynaload::loaded(void) const - { - return m_handle != 0; - } - - //////////////////////////////////////////////////////////////////////////// - // symbol management - - // test whether a function is exported by the library - // does not set the error flag if fails - bool dynaload::present(const std::string& name) - { - if (!loaded()) return false; -#ifdef MSWINDOWS - void* fn = (void*)GetProcAddress((HINSTANCE)m_handle,name.c_str()); -#else - void* fn = dlsym(m_handle,name.c_str()); -#endif - return fn != 0; - } - - // get the function as a generic pointer - void* dynaload::symbol(const std::string& name) - { - if (!loaded()) return 0; -#ifdef MSWINDOWS - void* fn = (void*)GetProcAddress((HINSTANCE)m_handle,name.c_str()); -#else - void* fn = dlsym(m_handle,name.c_str()); -#endif - if (!fn) - { - m_error = symbol_error; - m_text = last_error(); - } - return fn; - } - - //////////////////////////////////////////////////////////////////////////// - // error management - - // test whether there has been an error - bool dynaload::error(void) const - { - return m_error != no_error; - } - - // clear an error once it has been handled (or ignored) - void dynaload::clear_error(void) - { - m_error = no_error; - m_text = std::string(); - } - - // get the type of the error as indicated by the enum error_t - dynaload::error_t dynaload::error_type(void) const - { - return m_error; - } - - // get the text of the error as provided by the OS - std::string dynaload::error_text(void) const - { - return m_text; - } - - -//////////////////////////////////////////////////////////////////////////////// - -} // end namespace stlplus +//////////////////////////////////////////////////////////////////////////////// + +// Author: Andy Rushton +// Copyright: (c) Southampton University 1999-2004 +// (c) Andy Rushton 2004-2009 +// License: BSD License, see ../docs/license.html + +//////////////////////////////////////////////////////////////////////////////// +#include "dynaload.hpp" + +#ifdef MSWINDOWS +#include +#else +#include +#endif + +//////////////////////////////////////////////////////////////////////////////// + +#ifdef MSWINDOWS + +static std::string last_error(void) +{ + // get the last error code - if none, return the empty string + DWORD err = GetLastError(); + if (err == 0) return std::string(); + // get the system message for this error code + char* message; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + 0, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&message, + 0,0); + std::string result = message; + LocalFree(message); + // the error message is for some perverse reason newline terminated - remove this + if (result[result.size()-1] == '\n') + result.erase(result.end()-1); + if (result[result.size()-1] == '\r') + result.erase(result.end()-1); + return result; +} + +#else + +static std::string last_error(void) +{ + return std::string(dlerror()); +} + +#endif + +//////////////////////////////////////////////////////////////////////////////// + +namespace stlplus +{ + + //////////////////////////////////////////////////////////////////////////////// + // library management + + // construct the object but do not load + dynaload::dynaload(void) : m_handle(0) + { + } + + // construct and load + dynaload::dynaload(const std::string& library) : m_handle(0) + { + load(library); + } + + // destroy and unload if loaded + dynaload::~dynaload(void) + { + unload(); + } + + // load the library - return success or fail + bool dynaload::load(const std::string& library) + { +#ifdef MSWINDOWS + m_handle = (void*)LoadLibrary(library.c_str()); +#elif defined(CYGWIN) + m_handle = dlopen(library.c_str(),RTLD_NOW); +#else + std::string full_library = std::string("lib") + library + std::string(".so"); + m_handle = dlopen(full_library.c_str(),RTLD_NOW); +#endif + if (!m_handle) + { + m_error = load_error; + m_text = last_error(); + } + return loaded(); + } + + // unload the library if loaded + bool dynaload::unload(void) + { + if (!loaded()) return false; +#ifdef MSWINDOWS + int status = FreeLibrary((HINSTANCE)m_handle) ? 0 : 1; +#else + int status = dlclose(m_handle); +#endif + if (status != 0) + { + m_error = unload_error; + m_text = last_error(); + } + return status == 0; + } + + // test whether the library is loaded + bool dynaload::loaded(void) const + { + return m_handle != 0; + } + + //////////////////////////////////////////////////////////////////////////// + // symbol management + + // test whether a function is exported by the library + // does not set the error flag if fails + bool dynaload::present(const std::string& name) + { + if (!loaded()) return false; +#ifdef MSWINDOWS + void* fn = (void*)GetProcAddress((HINSTANCE)m_handle,name.c_str()); +#else + void* fn = dlsym(m_handle,name.c_str()); +#endif + return fn != 0; + } + + // get the function as a generic pointer + void* dynaload::symbol(const std::string& name) + { + if (!loaded()) return 0; +#ifdef MSWINDOWS + void* fn = (void*)GetProcAddress((HINSTANCE)m_handle,name.c_str()); +#else + void* fn = dlsym(m_handle,name.c_str()); +#endif + if (!fn) + { + m_error = symbol_error; + m_text = last_error(); + } + return fn; + } + + //////////////////////////////////////////////////////////////////////////// + // error management + + // test whether there has been an error + bool dynaload::error(void) const + { + return m_error != no_error; + } + + // clear an error once it has been handled (or ignored) + void dynaload::clear_error(void) + { + m_error = no_error; + m_text = std::string(); + } + + // get the type of the error as indicated by the enum error_t + dynaload::error_t dynaload::error_type(void) const + { + return m_error; + } + + // get the text of the error as provided by the OS + std::string dynaload::error_text(void) const + { + return m_text; + } + + +//////////////////////////////////////////////////////////////////////////////// + +} // end namespace stlplus