1 ////////////////////////////////////////////////////////////////////////////////
3 // Author: Andy Rushton
4 // Copyright: (c) Southampton University 1999-2004
5 // (c) Andy Rushton 2004-2009
6 // License: BSD License, see ../docs/license.html
8 ////////////////////////////////////////////////////////////////////////////////
9 #include "dynaload.hpp"
17 ////////////////////////////////////////////////////////////////////////////////
21 static std::string
last_error(void)
23 // get the last error code - if none, return the empty string
24 DWORD err
= GetLastError();
25 if (err
== 0) return std::string();
26 // get the system message for this error code
28 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM
|FORMAT_MESSAGE_IGNORE_INSERTS
,
31 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
34 std::string result
= message
;
36 // the error message is for some perverse reason newline terminated - remove this
37 if (result
[result
.size()-1] == '\n')
38 result
.erase(result
.end()-1);
39 if (result
[result
.size()-1] == '\r')
40 result
.erase(result
.end()-1);
46 static std::string
last_error(void)
48 return std::string(dlerror());
53 ////////////////////////////////////////////////////////////////////////////////
58 ////////////////////////////////////////////////////////////////////////////////
61 // construct the object but do not load
62 dynaload::dynaload(void) : m_handle(0)
67 dynaload::dynaload(const std::string
& library
) : m_handle(0)
72 // destroy and unload if loaded
73 dynaload::~dynaload(void)
78 // load the library - return success or fail
79 bool dynaload::load(const std::string
& library
)
82 m_handle
= (void*)LoadLibrary(library
.c_str());
84 m_handle
= dlopen(library
.c_str(),RTLD_NOW
);
86 std::string full_library
= std::string("lib") + library
+ std::string(".so");
87 m_handle
= dlopen(full_library
.c_str(),RTLD_NOW
);
92 m_text
= last_error();
97 // unload the library if loaded
98 bool dynaload::unload(void)
100 if (!loaded()) return false;
102 int status
= FreeLibrary((HINSTANCE
)m_handle
) ? 0 : 1;
104 int status
= dlclose(m_handle
);
108 m_error
= unload_error
;
109 m_text
= last_error();
114 // test whether the library is loaded
115 bool dynaload::loaded(void) const
117 return m_handle
!= 0;
120 ////////////////////////////////////////////////////////////////////////////
123 // test whether a function is exported by the library
124 // does not set the error flag if fails
125 bool dynaload::present(const std::string
& name
)
127 if (!loaded()) return false;
129 void* fn
= (void*)GetProcAddress((HINSTANCE
)m_handle
,name
.c_str());
131 void* fn
= dlsym(m_handle
,name
.c_str());
136 // get the function as a generic pointer
137 void* dynaload::symbol(const std::string
& name
)
139 if (!loaded()) return 0;
141 void* fn
= (void*)GetProcAddress((HINSTANCE
)m_handle
,name
.c_str());
143 void* fn
= dlsym(m_handle
,name
.c_str());
147 m_error
= symbol_error
;
148 m_text
= last_error();
153 ////////////////////////////////////////////////////////////////////////////
156 // test whether there has been an error
157 bool dynaload::error(void) const
159 return m_error
!= no_error
;
162 // clear an error once it has been handled (or ignored)
163 void dynaload::clear_error(void)
166 m_text
= std::string();
169 // get the type of the error as indicated by the enum error_t
170 dynaload::error_t
dynaload::error_type(void) const
175 // get the text of the error as provided by the OS
176 std::string
dynaload::error_text(void) const
182 ////////////////////////////////////////////////////////////////////////////////
184 } // end namespace stlplus