#include <DLL_Manager.h>
Public Methods | |
| ACE_DLL_Handle (void) | |
| Default construtor. More... | |
| ~ACE_DLL_Handle (void) | |
| Destructor. More... | |
| const ACE_TCHAR * | dll_name () const |
| Returns the name of the shared library (without prefixes or suffixes). More... | |
| int | open (const ACE_TCHAR *dll_name, int open_mode, ACE_SHLIB_HANDLE handle) |
| int | close (int unload=0) |
| Call to close the DLL object. If unload = 0, it only decrements the refcount, but if unload = 1, then it will actually unload the library when the refcount == 0;. More... | |
| sig_atomic_t | refcount (void) const |
| Return the current refcount. More... | |
| void * | symbol (const ACE_TCHAR *symbol_name, int ignore_errors=0) |
| If <symbol_name> is in the symbol table of the DLL a pointer to the <symbol_name> is returned. Otherwise, returns 0. Set the ignore_errors flag to supress logging errors if symbol_name isn't found. This is nice if you just want to probe a dll to see what's available, since missing functions in that case aren't really errors. More... | |
| ACE_SHLIB_HANDLE | get_handle (int become_owner=0) |
Private Methods | |
| auto_ptr< ACE_TString > | error (void) |
| Returns a pointer to a string explaining why <symbol> or <open> failed. This is used internal to print out the error to the log, but since this object is shared, we can't store or return the error to the caller. More... | |
| ACE_DLL_Handle (const ACE_DLL_Handle &) | |
| void | operator= (const ACE_DLL_Handle &) |
Private Attributes | |
| sig_atomic_t | refcount_ |
| ACE_TCHAR * | dll_name_ |
| Name of the shared library. More... | |
| ACE_SHLIB_HANDLE | handle_ |
| Handle to the actual library loaded by the OS. More... | |
Static Private Attributes | |
| sig_atomic_t | open_called_ = 0 |
| Keeps track of whether or not open() has ever been called. This helps get around problem on Linux, and perhaps other OS's, that seg-fault if dlerror() is called before the ld library has been initialized by a call to dlopen(). More... | |
This class is an wrapper over the various methods for utilizing a dynamically linked library (DLL), which is called a shared library on some platforms. It is refcounted and managed by ACE_DLL_Manager, so there will only be a single instance of this class for each dll loaded, no matter how many instances of ACE_DLL an application has open. Operations <open>, <close>, and <symbol> have been implemented to help opening/closing and extracting symbol information from a DLL, respectively.
Most of this class came from the original ACE_DLL class. ACE_DLL is now just an interface that passed all it's calls either directly or via ACE_DLL_Manager to this class for execution.
Definition at line 50 of file DLL_Manager.h.
|
|
Default construtor.
Definition at line 21 of file DLL_Manager.cpp. References ACE_SHLIB_INVALID_HANDLE, and ACE_TRACE.
00022 : refcount_ (0), 00023 dll_name_ (0), 00024 handle_ (ACE_SHLIB_INVALID_HANDLE) 00025 { 00026 ACE_TRACE ("ACE_DLL_Handle::ACE_DLL_Handle"); 00027 } |
|
|
Destructor.
Definition at line 29 of file DLL_Manager.cpp. References ACE_TRACE, close, and dll_name_.
|
|
|
|
|
|
Call to close the DLL object. If unload = 0, it only decrements the refcount, but if unload = 1, then it will actually unload the library when the refcount == 0;.
Definition at line 124 of file DLL_Manager.cpp. References ACE_DEBUG, ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_SHLIB_INVALID_HANDLE, ACE_TRACE, ACE::debug, ACE_OS::dlclose, handle_, ACE_Framework_Repository::instance, LM_DEBUG, LM_ERROR, refcount_, and ACE_Framework_Repository::remove_dll_components. Referenced by ACE_DLL_Manager::unload_dll, ACE_DLL_Manager::unload_policy, and ~ACE_DLL_Handle.
00125 {
00126 ACE_TRACE ("ACE_DLL_Handle::close");
00127 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00128
00129 int retval = 0;
00130
00131 // Since we don't actually unload the dll as soon as the refcount
00132 // reaches zero, we need to make sure we don't decrement it below
00133 // zero.
00134 if (this->refcount_ > 0)
00135 --this->refcount_;
00136 else
00137 this->refcount_ = 0;
00138
00139 if (this->refcount_ == 0 &&
00140 this->handle_ != ACE_SHLIB_INVALID_HANDLE &&
00141 unload == 1)
00142 {
00143 if (ACE::debug ())
00144 ACE_DEBUG ((LM_DEBUG,
00145 ACE_LIB_TEXT ("ACE_DLL_Handle::close: unloading %s\n"),
00146 this->dll_name_));
00147
00148 ACE_Framework_Repository* frPtr= ACE_Framework_Repository::instance ();
00149
00150 if (frPtr)
00151 {
00152 frPtr->remove_dll_components (this->dll_name_);
00153 }
00154
00155 retval = ACE_OS::dlclose (this->handle_);
00156 this->handle_ = ACE_SHLIB_INVALID_HANDLE;
00157 }
00158
00159 if (retval != 0)
00160 ACE_ERROR_RETURN ((LM_ERROR,
00161 ACE_LIB_TEXT ("ACE_DLL_Handle::close error: \"%s\"."),
00162 this->error ()->c_str ()),
00163 retval);
00164 return retval;
00165 }
|
|
|
Returns the name of the shared library (without prefixes or suffixes).
Definition at line 37 of file DLL_Manager.cpp. References ACE_TRACE, and dll_name_. Referenced by open.
|
|
|
Returns a pointer to a string explaining why <symbol> or <open> failed. This is used internal to print out the error to the log, but since this object is shared, we can't store or return the error to the caller.
Definition at line 228 of file DLL_Manager.cpp. References ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, ACE_TString, ACE_OS::dlerror, and error. Referenced by error, and symbol.
00229 {
00230 ACE_TRACE ("ACE_DLL_Handle::error");
00231 const ACE_TCHAR *error = ACE_OS::dlerror ();
00232 auto_ptr<ACE_TString> str
00233 (new ACE_TString (error ? error : ACE_LIB_TEXT ("no error")));
00234 return str;
00235 }
|
|
|
Return the handle to the caller. If <become_owner> is non-0 then caller assumes ownership of the handle so we decrement the retcount. Definition at line 196 of file DLL_Manager.cpp. References ACE_DEBUG, ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_SHLIB_HANDLE, ACE_SHLIB_INVALID_HANDLE, ACE_TRACE, handle_, LM_DEBUG, LM_ERROR, and refcount_. Referenced by ACE_DLL::get_handle.
00197 {
00198 ACE_TRACE ("ACE_DLL_Handle::get_handle");
00199 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00200
00201 ACE_SHLIB_HANDLE handle = ACE_SHLIB_INVALID_HANDLE;
00202
00203 if (this->refcount_ == 0 && become_owner != 0)
00204 ACE_ERROR_RETURN ((LM_ERROR,
00205 ACE_LIB_TEXT ("ACE_DLL_Handle::get_handle: ")
00206 ACE_LIB_TEXT ("cannot become owner, refcount == 0.\n")),
00207 ACE_SHLIB_INVALID_HANDLE);
00208 else if (become_owner != 0)
00209 {
00210 handle = this->handle_;
00211 if (--this->refcount_ == 0)
00212 this->handle_ = ACE_SHLIB_INVALID_HANDLE;
00213 }
00214
00215 ACE_DEBUG ((LM_DEBUG,
00216 ACE_LIB_TEXT ("ACE_DLL_Handle::get_handle: ")
00217 ACE_LIB_TEXT ("handle %s, refcount %d\n"),
00218 this->handle_ == ACE_SHLIB_INVALID_HANDLE ?
00219 ACE_LIB_TEXT ("invalid") : ACE_LIB_TEXT ("valid"),
00220 this->refcount_));
00221
00222 return handle;
00223 }
|
|
||||||||||||||||
|
This method opens and dynamically links <dll_name>. The default mode is <RTLD_LAZY>, which loads identifier symbols but not the symbols for functions, which are loaded dynamically on-demand. Other supported modes include: <RTLD_NOW>, which performs all necessary relocations when <dll_name> is first loaded and <RTLD_GLOBAL>, which makes symbols available for relocation processing of any other DLLs. Returns -1 on failure and 0 on success. Definition at line 44 of file DLL_Manager.cpp. References ACE_DEBUG, ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_SHLIB_HANDLE, ACE_SHLIB_INVALID_HANDLE, ACE_TCHAR, ACE_TRACE, ACE::debug, dll_name, dll_name_, ACE_OS::dlopen, handle_, ACE_Lib_Find::ldfind, LM_DEBUG, LM_ERROR, MAXPATHLEN, open_called_, refcount_, ACE_OS_String::strcat, ACE_OS_String::strcmp, ACE::strnew, and ACE_OS_String::strstr. Referenced by ACE_DLL_Manager::open_dll.
00047 {
00048 ACE_TRACE ("ACE_DLL_Handle::open");
00049 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00050
00051 //ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("dll_name: %s; open_mode: %d \n"),
00052 // dll_name,
00053 // open_mode));
00054
00055 if (this->dll_name_)
00056 {
00057 // Once dll_name_ has been set, it can't be changed..
00058 if (ACE_OS_String::strcmp (this->dll_name_, dll_name) != 0)
00059 ACE_ERROR_RETURN ((LM_ERROR,
00060 ACE_LIB_TEXT ("ACE_DLL_Handle::open: error, ")
00061 ACE_LIB_TEXT ("tried to reopen %s with name %s\n"),
00062 this->dll_name_, dll_name),
00063 -1);
00064 }
00065 else
00066 this->dll_name_ = ACE::strnew (dll_name);
00067
00068 if (!this->open_called_)
00069 this->open_called_ = 1;
00070
00071 // If it hasn't been loaded yet, go ahead and do that now.
00072 if (this->handle_ == ACE_SHLIB_INVALID_HANDLE)
00073 {
00074 if (handle)
00075 this->handle_ = handle;
00076 else
00077 {
00078 if (ACE::debug ())
00079 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_DLL_Handle::open: calling dlopen on ")
00080 ACE_LIB_TEXT ("\"%s\"\n"), dll_name));
00081 // Find out where the library is
00082 ACE_TCHAR dll_pathname[MAXPATHLEN + 1];
00083
00084 // Transform the pathname into the appropriate dynamic link library
00085 // by searching the ACE_LD_SEARCH_PATH.
00086 ACE_Lib_Find::ldfind (dll_name,
00087 dll_pathname,
00088 (sizeof dll_pathname / sizeof (ACE_TCHAR)));
00089
00090 // The ACE_SHLIB_HANDLE object is obtained.
00091 this->handle_ = ACE_OS::dlopen (dll_pathname,
00092 open_mode);
00093
00094 #if defined (AIX)
00095 if (this->handle_ == ACE_SHLIB_INVALID_HANDLE)
00096 {
00097 // AIX often puts the shared library file (most often named shr.o)
00098 // inside an archive library. If this is an archive library
00099 // name, then try appending [shr.o] and retry.
00100 if (0 != ACE_OS_String::strstr (dll_pathname, ACE_LIB_TEXT (".a")))
00101 {
00102 ACE_OS_String::strcat (dll_pathname, ACE_LIB_TEXT ("(shr.o)"));
00103 open_mode |= RTLD_MEMBER;
00104 this->handle_ = ACE_OS::dlopen (dll_pathname, open_mode);
00105 }
00106 }
00107 #endif /* AIX */
00108
00109 if (this->handle_ == ACE_SHLIB_INVALID_HANDLE)
00110 {
00111 ACE_ERROR_RETURN ((LM_ERROR,
00112 ACE_LIB_TEXT ("ACE_DLL_Manager_Ex::open: Invalid handle: %s\n"),
00113 this->error ()->c_str ()),
00114 -1);
00115 }
00116 }
00117 }
00118
00119 ++this->refcount_;
00120 return 0;
00121 }
|
|
|
|
|
|
Return the current refcount.
Definition at line 168 of file DLL_Manager.cpp. References refcount_. Referenced by ACE_DLL_Manager::unload_policy.
00169 {
00170 return this->refcount_;
00171 }
|
|
||||||||||||
|
If <symbol_name> is in the symbol table of the DLL a pointer to the <symbol_name> is returned. Otherwise, returns 0. Set the ignore_errors flag to supress logging errors if symbol_name isn't found. This is nice if you just want to probe a dll to see what's available, since missing functions in that case aren't really errors.
Definition at line 174 of file DLL_Manager.cpp. References ACE_ERROR_RETURN, ACE_GUARD_RETURN, ACE_LIB_TEXT, ACE_MT, ACE_TCHAR, ACE_TRACE, ACE_OS::dlsym, error, ACE_Auto_Basic_Array_Ptr::get, ACE_Lib_Find::ldname, and LM_ERROR. Referenced by ACE_DLL::symbol, and ACE_DLL_Manager::unload_dll.
00175 {
00176 ACE_TRACE ("ACE_DLL_Handle::symbol");
00177 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00178
00179 ACE_Auto_Array_Ptr <ACE_TCHAR> auto_name (ACE_Lib_Find::ldname (sym_name));
00180
00181 void *sym = ACE_OS::dlsym (this->handle_, auto_name.get ());
00182
00183 // Linux says that the symbol could be null and that it isn't an error.
00184 // So you should check the error message also, but since null symbols
00185 // won't do us much good anyway, let's still report an error.
00186 if (!sym && ignore_errors != 1)
00187 ACE_ERROR_RETURN ((LM_ERROR,
00188 ACE_LIB_TEXT ("ACE_DLL_Handle::symbol (\"%s\") \"%s\"."),
00189 auto_name.get (), this->error ()->c_str ()),
00190 0);
00191
00192 return sym;
00193 }
|
|
|
Name of the shared library.
Definition at line 110 of file DLL_Manager.h. Referenced by dll_name, open, and ~ACE_DLL_Handle. |
|
|
Handle to the actual library loaded by the OS.
Definition at line 113 of file DLL_Manager.h. Referenced by close, get_handle, and open. |
|
|
Keeps track of whether or not open() has ever been called. This helps get around problem on Linux, and perhaps other OS's, that seg-fault if dlerror() is called before the ld library has been initialized by a call to dlopen().
Definition at line 19 of file DLL_Manager.cpp. Referenced by open. |
|
|
Definition at line 107 of file DLL_Manager.h. Referenced by close, get_handle, open, and refcount. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002