6d4258b013e77fa60197235103cbd80c5b575110
[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 #ifdef __GNU_LIBRARY__
47 extern "C" { size_t strlen(const char* s) __THROW; }
48 #else
49 extern "C" { size_t strlen(const char* s); }
50 #endif
51
52
53 #define BAD(X)  ((X) == NULL)
54
55 // ----------------------------------------------------------------
56 //
57 // Create and initialize a shared library object to NULL
58 //
59 // ----------------------------------------------------------------
60 OSD_SharedLibrary::OSD_SharedLibrary():myHandle(NULL),myName(NULL){
61 }
62 // ----------------------------------------------------------------
63 //
64 // Create and initialize a shared library object to the
65 // name given as argument
66 //
67 // ----------------------------------------------------------------
68 OSD_SharedLibrary::OSD_SharedLibrary(const Standard_CString aName):myHandle(NULL) 
69 {
70   if (aName != NULL) {
71     myName = new char [(strlen (aName) + 1 )];
72     strcpy (myName,aName);
73   }
74 }
75 // ----------------------------------------------------------------
76 //
77 // Name: Returns the shared library name
78 //
79 // ----------------------------------------------------------------
80 Standard_CString  OSD_SharedLibrary::Name() const {
81   return myName; 
82 }
83 // ----------------------------------------------------------------
84 //
85 // SetName: Sets a name to a shared library object
86 //
87 // ----------------------------------------------------------------
88 void  OSD_SharedLibrary::SetName(const Standard_CString aName)  {
89   if (aName != NULL) {
90     myName = new char [(strlen (aName) + 1 )];
91     strcpy (myName,aName);
92   }
93 }
94 // ----------------------------------------------------------------
95 //
96 // DlOpen:   The dlopen function provides an interface to the dynamic 
97 // library loader to allow shared libraries to be loaded and called at
98 // runtime.  
99 // The dlopen function attempts to load filename, in the address space 
100 // of the process, resolving symbols as appropriate.  Any libraries that      
101 // filename depends upon are also loaded.
102 //
103 // If mode is RTLD_LAZY, then the runtime loader does symbol resolution 
104 // only as needed.  Typically, this means that the first call   
105 // to a function in the newly loaded library will cause the resolution 
106 // of the address of that function to occur.  
107 //
108 // If mode is RTLD_NOW, then the runtime loader must do all
109 // symbol binding during the dlopen call.  
110 // The dlopen function returns a handle that is used by dlsym or 
111 // dlclose call.  If there is an error, a NULLpointer is returned.
112 //
113 // If a NULL filename is specified, dlopen returns a handle for the main      
114 // executable, which allows access to dynamic symbols in the running program.
115 //
116 // ----------------------------------------------------------------
117 Standard_Boolean  OSD_SharedLibrary::DlOpen(const OSD_LoadMode aMode ) {
118 if (aMode == OSD_RTLD_LAZY){
119   myHandle = dlopen (myName,RTLD_LAZY);
120 }
121 else if (aMode == OSD_RTLD_NOW){
122   myHandle = dlopen (myName,RTLD_NOW);
123 }
124
125 if (!BAD(myHandle)){
126   return Standard_True;
127  }
128 else {
129   return Standard_False;
130  }
131 }
132 // ----------------------------------------------------------------
133 //
134 // DlSymb: The dlsym function returns the address of the        
135 // symbol name found in the shared library corresponding to handle.  
136 // If the symbol is not found, a NULL
137 // pointer is returned.
138 //
139 // ----------------------------------------------------------------
140 OSD_Function  OSD_SharedLibrary::DlSymb(const Standard_CString aName )const{
141 void (*fp)();
142 fp =  (void (*)()) dlsym (myHandle,aName);
143 if (!BAD(fp)){
144   return (OSD_Function)fp;
145  }
146 else {
147   return (OSD_Function)NULL;
148  }
149 }
150 // ----------------------------------------------------------------
151 //
152 //DlClose: The dlclose function deallocates the address space for the library
153 //corresponding to handle.  If any user function continues to call a symbol
154 //resolved in the address space of a library that has been since been deallo-
155 //cated by dlclose, the results are undefined.
156 //
157 // ----------------------------------------------------------------
158 void OSD_SharedLibrary::DlClose()const{
159  dlclose(myHandle);
160 }
161 // ----------------------------------------------------------------
162 //
163 // DlError:  returns a string   describing the last error that
164 // occurred from a call to dlopen, dlclose or dlsym.
165 //
166 // ----------------------------------------------------------------
167 Standard_CString OSD_SharedLibrary::DlError()const{
168 return (char*) dlerror();
169 }
170 // ----------------------------------------------------------------------------
171 // Destroy
172 // ----------------------------------------------------------------------------
173 void OSD_SharedLibrary::Destroy() {
174   if (myName != NULL) {
175      delete [] myName;
176      myName = NULL;
177      myHandle = NULL;
178   }
179 }
180
181 #else
182
183 //------------------------------------------------------------------------
184 //-------------------  Windows NT sources for OSD_SharedLibrary ----------
185 //------------------------------------------------------------------------
186
187 //it is important to define STRICT and enforce including <windows.h> before
188 //Standard_Macro.hxx undefines it and includes <windows.h> causing compilation errors
189 #ifndef STRICT
190 #define STRICT
191 #endif
192 #include <windows.h>
193
194
195 #include <OSD_Path.hxx>
196 #include <OSD_SharedLibrary.hxx>
197 #include <TCollection_AsciiString.hxx>
198
199 static DWORD              lastDLLError;
200 static Standard_Character errMsg[ 1024 ];
201
202 OSD_SharedLibrary :: OSD_SharedLibrary () {
203
204  myHandle = NULL;
205  myName   = NULL;
206
207 }  // end constructor ( 1 )
208
209 OSD_SharedLibrary :: OSD_SharedLibrary ( const Standard_CString aFilename ) {
210
211  myHandle = NULL;
212  myName   = NULL;
213
214  SetName ( aFilename );
215
216 }  // end constructro ( 2 )
217
218 void OSD_SharedLibrary :: SetName ( const Standard_CString aName ) {
219
220  OSD_Path                path ( aName );
221  TCollection_AsciiString name ( aName );
222
223  if ( myName != NULL )
224
225   delete [] myName;
226
227  myName = new Standard_Character[ strlen ( aName ) + 1 ];
228
229  strcpy ( myName, aName );
230
231  name = path.Name ();
232  name.AssignCat (  path.Extension ()  );
233
234  myHandle = GetModuleHandle (  name.ToCString ()  );
235
236 }  // end OSD_SharedLibrary :: SetName
237
238 Standard_CString OSD_SharedLibrary :: Name () const {
239
240  return myName;
241
242 }  // end OSD_SharedLibrary :: Name
243
244 Standard_Boolean OSD_SharedLibrary :: DlOpen ( const OSD_LoadMode /*Mode*/ ) {
245
246  Standard_Boolean retVal = Standard_True;
247
248  if (  (  myHandle ) == NULL &&
249        (  myHandle = ( HINSTANCE )LoadLibraryEx (
250                                    myName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH
251                                   )  ) == NULL
252  ) {
253  
254   lastDLLError = GetLastError ();
255   retVal       = Standard_False;
256  
257  }  // end if
258
259  return retVal;
260
261 }  // end OSD_SharedLibrary :: DlOpen
262
263 OSD_Function OSD_SharedLibrary :: DlSymb ( const Standard_CString Name ) const {
264
265  OSD_Function func = ( OSD_Function )GetProcAddress (  ( HMODULE )myHandle, Name  );
266
267  if ( func == NULL )
268
269   lastDLLError = GetLastError ();
270
271  return func;
272
273 }  // end OSD_SharedLibrary :: DlSymb
274
275 void OSD_SharedLibrary :: DlClose () const {
276
277  FreeLibrary (  ( HMODULE )myHandle  );
278
279 }  // end OSD_SharedLibrary :: DlClose
280
281 Standard_CString OSD_SharedLibrary :: DlError () const {
282
283  FormatMessage (
284   FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
285   0, lastDLLError, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), errMsg, 1024, ( va_list* )&myName
286  );
287
288  return errMsg;
289
290 }  // end OSD_SharedLibrary :: DlError
291
292 void OSD_SharedLibrary :: Destroy () {
293
294  if ( myName != NULL ) delete [] myName;
295
296 }  // end OSD_SharedLibrary :: Destroy
297
298 #endif