00001 
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 79134 2007-07-31 18:23:50Z johnnyw $")
00015 
00016   ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00017 
00018 
00019 
00020 
00021 ACE_DLL::ACE_DLL (int 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_ (0),
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       
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 
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 
00072 
00073 
00074 ACE_DLL::ACE_DLL (const ACE_TCHAR *dll_name,
00075                   int open_mode,
00076                   int 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 
00093 
00094 
00095 
00096 ACE_DLL::~ACE_DLL (void)
00097 {
00098   ACE_TRACE ("ACE_DLL::~ACE_DLL");
00099 
00100   this->close ();
00101 
00102   
00103   
00104   
00105   
00106   delete [] this->dll_name_;
00107 }
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 int
00121 ACE_DLL::open (const ACE_TCHAR *dll_filename,
00122                int open_mode,
00123                int 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                  int 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       
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 
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 
00195 
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   
00211   this->dll_handle_ = 0;
00212   delete [] this->dll_name_;
00213   this->dll_name_ = 0;
00214   this->close_handle_on_destruction_ = 0;
00215 
00216   return retval;
00217 }
00218 
00219 
00220 
00221 ACE_TCHAR *
00222 ACE_DLL::error (void) const
00223 {
00224   ACE_TRACE ("ACE_DLL::error");
00225   if (this->error_)
00226     return
00227       const_cast<ACE_TCHAR *> (ACE_TEXT ("Error: check log for details."));
00228 
00229   return 0;
00230 }
00231 
00232 
00233 
00234 
00235 
00236 ACE_SHLIB_HANDLE
00237 ACE_DLL::get_handle (int become_owner) const
00238 {
00239   ACE_TRACE ("ACE_DLL::get_handle");
00240 
00241   ACE_SHLIB_HANDLE handle = ACE_SHLIB_INVALID_HANDLE;
00242 
00243   if (this->dll_handle_)
00244     handle = this->dll_handle_->get_handle (become_owner);
00245 
00246   return handle;
00247 }
00248 
00249 
00250 
00251 
00252 int
00253 ACE_DLL::set_handle (ACE_SHLIB_HANDLE handle,
00254                      int close_handle_on_destruction)
00255 {
00256   ACE_TRACE ("ACE_DLL::set_handle");
00257 
00258   
00259   
00260   ACE_TCHAR temp[ACE_UNIQUE_NAME_LEN];
00261   ACE_OS::unique_name (this, temp, ACE_UNIQUE_NAME_LEN);
00262 
00263   return this->open_i (temp, 1, close_handle_on_destruction, handle);
00264 }
00265 
00266 ACE_END_VERSIONED_NAMESPACE_DECL