0022972: Eliminate macro definitions that has compiler-provided analogs (WNT and...
[occt.git] / src / OSD / OSD_SharedLibrary.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _WIN32
16
17
18 #include <OSD_Function.hxx>
19 #include <OSD_LoadMode.hxx>
20 #include <OSD_SharedLibrary.hxx>
21
22 #include <stdio.h>
23 #ifdef __some_crappy_system__
24 /*
25  * Values for 'mode' argument in dlopen().
26  *
27 */
28 #define RTLD_LAZY               1
29 #define RTLD_NOW                2
30 /*
31  * Interface to rld via unsupported __rld_libdl_interface() call.
32  *
33  */
34 #define _LIBDL_RLD_DLOPEN       1
35 #define _LIBDL_RLD_DLCLOSE      2
36 #define _LIBDL_RLD_DLSYM        3
37 #define _LIBDL_RLD_DLERROR      4
38 extern "C" {void        *dlopen(char *path, int mode);}
39 extern "C" {void*   dlsym   (       void*  handle,char* name);}
40 extern "C" {int     dlclose (       void  *handle  );}
41 extern "C" {void    *dlerror (void);}
42 #endif
43
44 #include <dlfcn.h>
45
46 extern "C" {size_t  strlen  (const  char*  s      );}
47
48
49 #define BAD(X)  ((X) == NULL)
50
51 // ----------------------------------------------------------------
52 //
53 // Create and initialize a shared library object to NULL
54 //
55 // ----------------------------------------------------------------
56 OSD_SharedLibrary::OSD_SharedLibrary():myHandle(NULL),myName(NULL){
57 }
58 // ----------------------------------------------------------------
59 //
60 // Create and initialize a shared library object to the
61 // name given as argument
62 //
63 // ----------------------------------------------------------------
64 OSD_SharedLibrary::OSD_SharedLibrary(const Standard_CString aName):myHandle(NULL) 
65 {
66   if (aName != NULL) {
67     myName = new char [(strlen (aName) + 1 )];
68     strcpy (myName,aName);
69   }
70 }
71 // ----------------------------------------------------------------
72 //
73 // Name: Returns the shared library name
74 //
75 // ----------------------------------------------------------------
76 Standard_CString  OSD_SharedLibrary::Name() const {
77   return myName; 
78 }
79 // ----------------------------------------------------------------
80 //
81 // SetName: Sets a name to a shared library object
82 //
83 // ----------------------------------------------------------------
84 void  OSD_SharedLibrary::SetName(const Standard_CString aName)  {
85   if (aName != NULL) {
86     myName = new char [(strlen (aName) + 1 )];
87     strcpy (myName,aName);
88   }
89 }
90 // ----------------------------------------------------------------
91 //
92 // DlOpen:   The dlopen function provides an interface to the dynamic 
93 // library loader to allow shared libraries to be loaded and called at
94 // runtime.  
95 // The dlopen function attempts to load filename, in the address space 
96 // of the process, resolving symbols as appropriate.  Any libraries that      
97 // filename depends upon are also loaded.
98 //
99 // If mode is RTLD_LAZY, then the runtime loader does symbol resolution 
100 // only as needed.  Typically, this means that the first call   
101 // to a function in the newly loaded library will cause the resolution 
102 // of the address of that function to occur.  
103 //
104 // If mode is RTLD_NOW, then the runtime loader must do all
105 // symbol binding during the dlopen call.  
106 // The dlopen function returns a handle that is used by dlsym or 
107 // dlclose call.  If there is an error, a NULLpointer is returned.
108 //
109 // If a NULL filename is specified, dlopen returns a handle for the main      
110 // executable, which allows access to dynamic symbols in the running program.
111 //
112 // ----------------------------------------------------------------
113 Standard_Boolean  OSD_SharedLibrary::DlOpen(const OSD_LoadMode aMode ) {
114 if (aMode == OSD_RTLD_LAZY){
115   myHandle = dlopen (myName,RTLD_LAZY);
116 }
117 else if (aMode == OSD_RTLD_NOW){
118   myHandle = dlopen (myName,RTLD_NOW);
119 }
120
121 if (!BAD(myHandle)){
122   return Standard_True;
123  }
124 else {
125   return Standard_False;
126  }
127 }
128 // ----------------------------------------------------------------
129 //
130 // DlSymb: The dlsym function returns the address of the        
131 // symbol name found in the shared library corresponding to handle.  
132 // If the symbol is not found, a NULL
133 // pointer is returned.
134 //
135 // ----------------------------------------------------------------
136 OSD_Function  OSD_SharedLibrary::DlSymb(const Standard_CString aName )const{
137 void (*fp)();
138 fp =  (void (*)()) dlsym (myHandle,aName);
139 if (!BAD(fp)){
140   return (OSD_Function)fp;
141  }
142 else {
143   return (OSD_Function)NULL;
144  }
145 }
146 // ----------------------------------------------------------------
147 //
148 //DlClose: The dlclose function deallocates the address space for the library
149 //corresponding to handle.  If any user function continues to call a symbol
150 //resolved in the address space of a library that has been since been deallo-
151 //cated by dlclose, the results are undefined.
152 //
153 // ----------------------------------------------------------------
154 void OSD_SharedLibrary::DlClose()const{
155  dlclose(myHandle);
156 }
157 // ----------------------------------------------------------------
158 //
159 // DlError:  returns a string   describing the last error that
160 // occurred from a call to dlopen, dlclose or dlsym.
161 //
162 // ----------------------------------------------------------------
163 Standard_CString OSD_SharedLibrary::DlError()const{
164 return (char*) dlerror();
165 }
166 // ----------------------------------------------------------------------------
167 // Destroy
168 // ----------------------------------------------------------------------------
169 void OSD_SharedLibrary::Destroy() {
170   if (myName != NULL) {
171      delete [] myName;
172      myName = NULL;
173      myHandle = NULL;
174   }
175 }
176
177 #else
178
179 //------------------------------------------------------------------------
180 //-------------------  Windows NT sources for OSD_SharedLibrary ----------
181 //------------------------------------------------------------------------
182
183 //it is important to define STRICT and enforce including <windows.h> before
184 //Standard_Macro.hxx undefines it and includes <windows.h> causing compilation errors
185 #ifndef STRICT
186 #define STRICT
187 #endif
188 #include <windows.h>
189
190
191 #include <OSD_Path.hxx>
192 #include <OSD_SharedLibrary.hxx>
193 #include <TCollection_AsciiString.hxx>
194
195 static DWORD              lastDLLError;
196 static Standard_Character errMsg[ 1024 ];
197
198 OSD_SharedLibrary :: OSD_SharedLibrary () {
199
200  myHandle = NULL;
201  myName   = NULL;
202
203 }  // end constructor ( 1 )
204
205 OSD_SharedLibrary :: OSD_SharedLibrary ( const Standard_CString aFilename ) {
206
207  myHandle = NULL;
208  myName   = NULL;
209
210  SetName ( aFilename );
211
212 }  // end constructro ( 2 )
213
214 void OSD_SharedLibrary :: SetName ( const Standard_CString aName ) {
215
216  OSD_Path                path ( aName );
217  TCollection_AsciiString name ( aName );
218
219  if ( myName != NULL )
220
221   delete [] myName;
222
223  myName = new Standard_Character[ strlen ( aName ) + 1 ];
224
225  strcpy ( myName, aName );
226
227  name = path.Name ();
228  name.AssignCat (  path.Extension ()  );
229
230  myHandle = GetModuleHandle (  name.ToCString ()  );
231
232 }  // end OSD_SharedLibrary :: SetName
233
234 Standard_CString OSD_SharedLibrary :: Name () const {
235
236  return myName;
237
238 }  // end OSD_SharedLibrary :: Name
239
240 Standard_Boolean OSD_SharedLibrary :: DlOpen ( const OSD_LoadMode /*Mode*/ ) {
241
242  Standard_Boolean retVal = Standard_True;
243
244  if (  (  myHandle ) == NULL &&
245        (  myHandle = ( HINSTANCE )LoadLibraryEx (
246                                    myName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH
247                                   )  ) == NULL
248  ) {
249  
250   lastDLLError = GetLastError ();
251   retVal       = Standard_False;
252  
253  }  // end if
254
255  return retVal;
256
257 }  // end OSD_SharedLibrary :: DlOpen
258
259 OSD_Function OSD_SharedLibrary :: DlSymb ( const Standard_CString Name ) const {
260
261  OSD_Function func = ( OSD_Function )GetProcAddress (  ( HMODULE )myHandle, Name  );
262
263  if ( func == NULL )
264
265   lastDLLError = GetLastError ();
266
267  return func;
268
269 }  // end OSD_SharedLibrary :: DlSymb
270
271 void OSD_SharedLibrary :: DlClose () const {
272
273  FreeLibrary (  ( HMODULE )myHandle  );
274
275 }  // end OSD_SharedLibrary :: DlClose
276
277 Standard_CString OSD_SharedLibrary :: DlError () const {
278
279  FormatMessage (
280   FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
281   0, lastDLLError, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), errMsg, 1024, ( va_list* )&myName
282  );
283
284  return errMsg;
285
286 }  // end OSD_SharedLibrary :: DlError
287
288 void OSD_SharedLibrary :: Destroy () {
289
290  if ( myName != NULL ) delete [] myName;
291
292 }  // end OSD_SharedLibrary :: Destroy
293
294 #endif