Merge pull request #2222 from jwillemsen/jwi-dllexportwarning
[ACE_TAO.git] / TAO / tests / POA / On_Demand_Loading / Servant_Manager.cpp
blob7ffeef724c6deef6e8b45d36fa961819a68cfe8f
2 //=============================================================================
3 /**
4 * @file Servant_Manager.cpp
6 * Implementation of the helper class for the ServantActivator_i
7 * and the ServantLocator_i.
9 * @author Kirthika Parameswaran <kirthika@cs.wustl.edu>
11 //=============================================================================
14 #include "Servant_Manager.h"
15 #include "tao/debug.h"
17 // Initialization.
18 ServantManager_i::ServantManager_i (CORBA::ORB_ptr orb)
19 : orb_ (CORBA::ORB::_duplicate (orb))
23 // Destruction.
24 ServantManager_i::~ServantManager_i ()
28 // This method loads the dynamically linked DLL which is the servant
29 // and returns the servant object which is then used for other
30 // operations in the DLL.
32 PortableServer::Servant
33 ServantManager_i::obtain_servant (const ACE_TCHAR *str,
34 PortableServer::POA_ptr poa)
36 // The string format is <dllname:factory_function> that must be
37 // parsed.
38 this->parse_string (str);
40 // Create the DLL object.
41 ACE_DLL *dll = 0;
43 ACE_NEW_RETURN (dll,
44 ACE_DLL,
45 0);
47 // Obtain the ObjectId from the string argument.
49 PortableServer::ObjectId_var oid =
50 PortableServer::string_to_ObjectId (ACE_TEXT_ALWAYS_CHAR (str));
52 if (TAO_debug_level > 0)
53 ACE_DEBUG ((LM_DEBUG,
54 "before bind\n"));
55 // Make an HASH_MAP entry by binding the object_id and the DLL
56 // object associated with it together.
57 if (this->servant_map_.bind (oid.in (),
58 dll) == -1)
59 ACE_ERROR_RETURN ((LM_ERROR,
60 "%p\n",
61 "Bind failed"),
62 0);
63 // Now that the dll name is available we open the dll.
64 if (dll->open (dllname_.c_str ()) == -1)
65 ACE_ERROR_RETURN ((LM_ERROR,
66 "%p",
67 dll->error ()),
68 0);
70 // The next step is to obtain the symbol for the function that will
71 // create the servant object and return it.
73 // Cannot go from void* to function pointer directly. Cast the void*
74 // to long first.
75 void *symbol = dll->symbol (create_symbol_.c_str ());
76 intptr_t function = reinterpret_cast<intptr_t> (symbol);
78 SERVANT_FACTORY servant_creator =
79 reinterpret_cast<SERVANT_FACTORY> (function);
81 // Checking whether it is possible to create the servant.
82 if (servant_creator == 0)
83 ACE_ERROR_RETURN ((LM_ERROR,
84 "%p",
85 dll->error ()),
86 0);
88 // Now create and return the servant using the <servant_creator>
89 // factory function.
90 return (*servant_creator) (this->orb_.in (),
91 poa);
94 // The objectID is in a format of dllname:factory_function which has
95 // to be parsed and separated into tokens to be used.
97 void
98 ServantManager_i::parse_string (const ACE_TCHAR *s)
100 // The format of the objectid is <dll:factory_function>. This
101 // string is parsed to obtain the dll name and the function name
102 // which will create trhe servant and return it to us.
104 ACE_TString str (s);
106 ACE_TString::size_type index = str.find (':');
107 // On error, npos is returned.
108 if (index == ACE_CString::npos)
109 ACE_ERROR ((LM_ERROR,
110 "Required character absent!\n"));
112 // The index gives us the location which is equivalent to the size
113 // of the dllname_ string.
114 this->dllname_ = str.substr (0, index);
116 // Obtain the substring from the offset which is one greater than
117 // the location of ':'.
118 this->create_symbol_ = str.substr (index + 1);
120 if (TAO_debug_level > 0)
121 ACE_DEBUG ((LM_DEBUG,
122 "the servant dll:%s\n the factory_function:%s\n",
123 this->dllname_.c_str (),
124 this->create_symbol_.c_str ()));
127 // This method returns an ObjectId when given a DLL name and the
128 // factory function to be invoked in the DLL. The format of the
129 // ObjectId is libname:factory_function.
131 PortableServer::ObjectId_var
132 ServantManager_i::create_dll_object_id (const char *libname,
133 const char *factory_function)
135 ACE_CString format_string = libname;
136 format_string += ":";
137 format_string += factory_function;
139 ACE_DEBUG ((LM_DEBUG,
140 "format-string is %C\n",
141 format_string.c_str ()));
142 // The object ID is created.
143 PortableServer::ObjectId_var oid =
144 PortableServer::string_to_ObjectId (format_string.c_str ());
145 return oid;
148 // This method destroys the servant and its caretaking DLL object.
150 void
151 ServantManager_i::destroy_servant (PortableServer::Servant servant,
152 const PortableServer::ObjectId &oid)
154 // The servant is destroyed.
155 delete servant;
157 // Since the servant is no more the DLL object associated with it
158 // has to be destroyed too.
160 ACE_DLL *dll = 0;
162 // Since the servant is no more the DLL object associated with it
163 // has to be destroyed too.
165 if (this->servant_map_.unbind (oid,
166 dll) == -1)
167 ACE_ERROR ((LM_ERROR,
168 "%p\n",
169 "Unbind failed!\n"));
170 delete dll;