DLL.cpp

Go to the documentation of this file.
00001 // $Id: DLL.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #include "ace/DLL.h"
00004 
00005 #include "ace/Log_Msg.h"
00006 #include "ace/ACE.h"
00007 #include "ace/DLL_Manager.h"
00008 #include "ace/OS_NS_string.h"
00009 #include "ace/OS_NS_dlfcn.h"
00010 #include "ace/OS_NS_Thread.h"
00011 
00012 #include <algorithm>
00013 
00014 ACE_RCSID(ace, DLL, "$Id: DLL.cpp 80826 2008-03-04 14:51:23Z wotte $")
00015 
00016   ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00017 
00018 // Default constructor. Also, by default, the object will be closed
00019 // before it is destroyed.
00020 
00021 ACE_DLL::ACE_DLL (bool close_handle_on_destruction)
00022   : open_mode_ (0),
00023     dll_name_ (0),
00024     close_handle_on_destruction_ (close_handle_on_destruction),
00025     dll_handle_ (0),
00026     error_ (0)
00027 {
00028   ACE_TRACE ("ACE_DLL::ACE_DLL (int)");
00029 }
00030 
00031 ACE_DLL::ACE_DLL (const ACE_DLL &rhs)
00032   : open_mode_ (0),
00033     dll_name_ (0),
00034     close_handle_on_destruction_ (false),
00035     dll_handle_ (0),
00036     error_ (0)
00037 {
00038   ACE_TRACE ("ACE_DLL::ACE_DLL (const ACE_DLL &)");
00039 
00040   if (rhs.dll_name_
00041       // This will automatically up the refcount.
00042       && this->open (rhs.dll_name_,
00043                      rhs.open_mode_,
00044                      rhs.close_handle_on_destruction_) != 0
00045       && ACE::debug ())
00046     ACE_ERROR ((LM_ERROR,
00047     ACE_TEXT ("ACE_DLL::copy_ctor: error: %s\n"),
00048     this->error ()));
00049 }
00050 
00051 // Assignment operator
00052 
00053 ACE_DLL &
00054 ACE_DLL::operator= (const ACE_DLL &rhs)
00055 {
00056   ACE_TRACE ("ACE_DLL::operator= (const ACE_DLL &)");
00057 
00058   ACE_DLL tmp (rhs);
00059 
00060   std::swap (this->open_mode_, tmp.open_mode_);
00061   std::swap (this->dll_name_, tmp.dll_name_);
00062   std::swap (this->close_handle_on_destruction_,
00063              tmp.close_handle_on_destruction_);
00064   std::swap (this->dll_handle_, tmp.dll_handle_);
00065   std::swap (this->error_, tmp.error_);
00066 
00067   return *this;
00068 }
00069 
00070 
00071 // If the library name and the opening mode are specified than on
00072 // object creation the library is implicitly opened.
00073 
00074 ACE_DLL::ACE_DLL (const ACE_TCHAR *dll_name,
00075                   int open_mode,
00076                   bool close_handle_on_destruction)
00077   : open_mode_ (open_mode),
00078     dll_name_ (0),
00079     close_handle_on_destruction_ (close_handle_on_destruction),
00080     dll_handle_ (0),
00081     error_ (0)
00082 {
00083   ACE_TRACE ("ACE_DLL::ACE_DLL");
00084 
00085   if (this->open (dll_name, this->open_mode_, close_handle_on_destruction) != 0
00086       && ACE::debug ())
00087     ACE_ERROR ((LM_ERROR,
00088                 ACE_TEXT ("ACE_DLL::open: error calling open: %s\n"),
00089                 this->error ()));
00090 }
00091 
00092 // The library is closed before the class gets destroyed depending on
00093 // the close_handle_on_destruction value specified which is stored in
00094 // close_handle_on_destruction_.
00095 
00096 ACE_DLL::~ACE_DLL (void)
00097 {
00098   ACE_TRACE ("ACE_DLL::~ACE_DLL");
00099 
00100   this->close ();
00101 
00102   // Normally delete()d in ACE_DLL::close().  However, that may not
00103   // occur if full ACE_DLL initialization is interrupted due to errors
00104   // (e.g. attempting to open a DSO/DLL that does not exist).  Make
00105   // sure this->dll_name_ is deallocated.
00106   delete [] this->dll_name_;
00107 }
00108 
00109 // This method opens the library based on the mode specified using the
00110 // ACE_SHLIB_HANDLE which is obtained on making the ACE_OS::dlopen call.
00111 // The default mode is:
00112 // RTLD_LAZY     Only references to data symbols are relocate when the
00113 //               object is first loaded.
00114 // The other modes include:
00115 //  RTLD_NOW     All necessary relocations are performed when the
00116 //               object is first loaded.
00117 //  RTLD_GLOBAL  The object symbols are made available for the
00118 //               relocation processing of any other object.
00119 
00120 int
00121 ACE_DLL::open (const ACE_TCHAR *dll_filename,
00122                int open_mode,
00123                bool close_handle_on_destruction)
00124 {
00125   ACE_TRACE ("ACE_DLL::open");
00126 
00127   return open_i (dll_filename, open_mode, close_handle_on_destruction);
00128 }
00129 
00130 int
00131 ACE_DLL::open_i (const ACE_TCHAR *dll_filename,
00132                  int open_mode,
00133                  bool close_handle_on_destruction,
00134                  ACE_SHLIB_HANDLE handle)
00135 {
00136   ACE_TRACE ("ACE_DLL::open_i");
00137 
00138   this->error_ = 0;
00139 
00140   if (!dll_filename)
00141     {
00142       if (ACE::debug ())
00143         ACE_ERROR ((LM_ERROR,
00144                     ACE_TEXT ("ACE_DLL::open_i: dll_name is %s\n"),
00145                     this->dll_name_ == 0 ? ACE_TEXT ("(null)")
00146         : this->dll_name_));
00147       return -1;
00148     }
00149 
00150   if (this->dll_handle_)
00151     {
00152       // If we have a good handle and its the same name, just return.
00153       if (ACE_OS::strcmp (this->dll_name_, dll_filename) == 0)
00154         return 0;
00155       else
00156         this->close ();
00157     }
00158 
00159   if (!this->dll_name_)
00160     this->dll_name_ = ACE::strnew (dll_filename);
00161 
00162   this->open_mode_ = open_mode;
00163   this->close_handle_on_destruction_ = close_handle_on_destruction;
00164 
00165   this->dll_handle_ = ACE_DLL_Manager::instance()->open_dll (this->dll_name_,
00166                                                              this->open_mode_,
00167                                                              handle);
00168 
00169   if (!this->dll_handle_)
00170     this->error_ = 1;
00171 
00172   return this->error_ ? -1 : 0;
00173 }
00174 
00175 // The symbol refernce of the name specified is obtained.
00176 
00177 void *
00178 ACE_DLL::symbol (const ACE_TCHAR *sym_name, int ignore_errors)
00179 {
00180   ACE_TRACE ("ACE_DLL::symbol");
00181 
00182   this->error_ = 0;
00183 
00184   void *sym = 0;
00185   if (this->dll_handle_)
00186     sym = this->dll_handle_->symbol (sym_name, ignore_errors);
00187 
00188   if (!sym)
00189     this->error_ = 1;
00190 
00191   return sym;
00192 }
00193 
00194 // The library is closed using the ACE_SHLIB_HANDLE object, i.e., the
00195 // shared object is now disassociated form the current process.
00196 
00197 int
00198 ACE_DLL::close (void)
00199 {
00200   ACE_TRACE ("ACE_DLL::close");
00201 
00202   int retval = 0;
00203 
00204   if (this->dll_handle_
00205       && this->close_handle_on_destruction_
00206       && this->dll_name_
00207       && (retval = ACE_DLL_Manager::instance ()->close_dll (this->dll_name_)) != 0)
00208     this->error_ = 1;
00209 
00210   // Even if close_dll() failed, go ahead and cleanup.
00211   this->dll_handle_ = 0;
00212   delete [] this->dll_name_;
00213   this->dll_name_ = 0;
00214   this->close_handle_on_destruction_ = false;
00215 
00216   return retval;
00217 }
00218 
00219 // This method is used return the last error of a library operation.
00220 
00221 ACE_TCHAR *
00222 ACE_DLL::error (void) const
00223 {
00224   ACE_TRACE ("ACE_DLL::error");
00225   if (this->error_)
00226     {
00227       return ACE_OS::dlerror ();
00228     }
00229 
00230   return 0;
00231 }
00232 
00233 // Return the handle to the user either temporarily or forever, thus
00234 // orphaning it. If 0 means the user wants the handle forever and if 1
00235 // means the user temporarily wants to take the handle.
00236 
00237 ACE_SHLIB_HANDLE
00238 ACE_DLL::get_handle (int become_owner) const
00239 {
00240   ACE_TRACE ("ACE_DLL::get_handle");
00241 
00242   ACE_SHLIB_HANDLE handle = ACE_SHLIB_INVALID_HANDLE;
00243 
00244   if (this->dll_handle_)
00245     handle = this->dll_handle_->get_handle (become_owner);
00246 
00247   return handle;
00248 }
00249 
00250 // Set the handle for the DLL. By default, the object will be closed
00251 // before it is destroyed.
00252 
00253 int
00254 ACE_DLL::set_handle (ACE_SHLIB_HANDLE handle,
00255                      bool close_handle_on_destruction)
00256 {
00257   ACE_TRACE ("ACE_DLL::set_handle");
00258 
00259   // Create a unique name.  Note that this name is only quaranteed
00260   // to be unique for the life of this object.
00261   ACE_TCHAR temp[ACE_UNIQUE_NAME_LEN];
00262   ACE_OS::unique_name (this, temp, ACE_UNIQUE_NAME_LEN);
00263 
00264   return this->open_i (temp, 1, close_handle_on_destruction, handle);
00265 }
00266 
00267 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:39 2010 for ACE by  doxygen 1.4.7