333f9c1bfa99768123fe3ecae0a059e2e377d121
[occt.git] / src / OSD / OSD_SharedLibrary.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #ifndef WNT
25
26 #include <OSD_LoadMode.hxx>
27 #include <OSD_SharedLibrary.ixx>
28 #include <OSD_Function.hxx>
29
30 #include <stdio.h>
31
32 #ifdef HAVE_MALLOC_H
33 # include <malloc.h>
34 #endif
35
36 #ifdef __some_crappy_system__
37 /*
38  * Values for 'mode' argument in dlopen().
39  *
40 */
41 #define RTLD_LAZY               1
42 #define RTLD_NOW                2
43 /*
44  * Interface to rld via unsupported __rld_libdl_interface() call.
45  *
46  */
47 #define _LIBDL_RLD_DLOPEN       1
48 #define _LIBDL_RLD_DLCLOSE      2
49 #define _LIBDL_RLD_DLSYM        3
50 #define _LIBDL_RLD_DLERROR      4
51 extern "C" {void        *dlopen(char *path, int mode);}
52 extern "C" {void*   dlsym   (       void*  handle,char* name);}
53 extern "C" {int     dlclose (       void  *handle  );}
54 extern "C" {void    *dlerror (void);}
55 #endif
56
57 #ifdef HAVE_DLFCN_H
58 # include <dlfcn.h>
59 #endif
60
61 #ifdef HAVE_DL_H
62 # include <dl.h>
63 #endif
64
65 extern "C" {size_t  strlen  (const  char*  s      );}
66
67
68 #define BAD(X)  ((X) == NULL)
69
70 // ----------------------------------------------------------------
71 //
72 // Create and initialize a shared library object to NULL
73 //
74 // ----------------------------------------------------------------
75 OSD_SharedLibrary::OSD_SharedLibrary():myHandle(NULL),myName(NULL){
76 }
77 // ----------------------------------------------------------------
78 //
79 // Create and initialize a shared library object to the
80 // name given as argument
81 //
82 // ----------------------------------------------------------------
83 OSD_SharedLibrary::OSD_SharedLibrary(const Standard_CString aName):myHandle(NULL) 
84 {
85   if (aName != NULL) {
86     myName = new char [(strlen (aName) + 1 )];
87     strcpy (myName,aName);
88   }
89 }
90 // ----------------------------------------------------------------
91 //
92 // Name: Returns the shared library name
93 //
94 // ----------------------------------------------------------------
95 Standard_CString  OSD_SharedLibrary::Name() const {
96   return myName; 
97 }
98 // ----------------------------------------------------------------
99 //
100 // SetName: Sets a name to a shared library object
101 //
102 // ----------------------------------------------------------------
103 void  OSD_SharedLibrary::SetName(const Standard_CString aName)  {
104   if (aName != NULL) {
105     myName = new char [(strlen (aName) + 1 )];
106     strcpy (myName,aName);
107   }
108 }
109 // ----------------------------------------------------------------
110 //
111 // DlOpen:   The dlopen function provides an interface to the dynamic 
112 // library loader to allow shared libraries to be loaded and called at
113 // runtime.  
114 // The dlopen function attempts to load filename, in the address space 
115 // of the process, resolving symbols as appropriate.  Any libraries that      
116 // filename depends upon are also loaded.
117 //
118 // If mode is RTLD_LAZY, then the runtime loader does symbol resolution 
119 // only as needed.  Typically, this means that the first call   
120 // to a function in the newly loaded library will cause the resolution 
121 // of the address of that function to occur.  
122 //
123 // If mode is RTLD_NOW, then the runtime loader must do all
124 // symbol binding during the dlopen call.  
125 // The dlopen function returns a handle that is used by dlsym or 
126 // dlclose call.  If there is an error, a NULLpointer is returned.
127 //
128 // If a NULL filename is specified, dlopen returns a handle for the main      
129 // executable, which allows access to dynamic symbols in the running program.
130 //
131 // ----------------------------------------------------------------
132 Standard_Boolean  OSD_SharedLibrary::DlOpen(const OSD_LoadMode aMode ) {
133
134 #ifdef HAVE_DL_H
135 if (aMode == OSD_RTLD_LAZY){
136 //  myHandle = cxxshl_load(myName, BIND_FIRST | BIND_TOGETHER | BIND_DEFERRED | BIND_VERBOSE | DYNAMIC_PATH, 0L);
137   myHandle = shl_load(myName, BIND_FIRST | BIND_TOGETHER | BIND_DEFERRED | BIND_VERBOSE | DYNAMIC_PATH, 0L);
138 }
139 else if (aMode == OSD_RTLD_NOW){
140 //  myHandle = cxxshl_load(myName, BIND_FIRST | BIND_TOGETHER | BIND_IMMEDIATE | BIND_VERBOSE | DYNAMIC_PATH, 0L);
141   myHandle = shl_load(myName, BIND_FIRST | BIND_TOGETHER | BIND_IMMEDIATE | BIND_VERBOSE | DYNAMIC_PATH, 0L);
142
143 }
144 #else
145 if (aMode == OSD_RTLD_LAZY){
146   myHandle = dlopen (myName,RTLD_LAZY);
147 }
148 else if (aMode == OSD_RTLD_NOW){
149   myHandle = dlopen (myName,RTLD_NOW);
150 }
151 #endif
152
153 if (!BAD(myHandle)){
154   return Standard_True;
155  }
156 else {
157   return Standard_False;
158  }
159 }
160 // ----------------------------------------------------------------
161 //
162 // DlSymb: The dlsym function returns the address of the        
163 // symbol name found in the shared library corresponding to handle.  
164 // If the symbol is not found, a NULL
165 // pointer is returned.
166 //
167 // ----------------------------------------------------------------
168 OSD_Function  OSD_SharedLibrary::DlSymb(const Standard_CString aName )const{
169
170 #ifndef HAVE_DL_H
171 void (*fp)();
172 fp =  (void (*)()) dlsym (myHandle,aName);
173 if (!BAD(fp)){
174   return (OSD_Function)fp;
175  }
176 else {
177   return (OSD_Function)NULL;
178  }
179 #else
180   void *adr_get = NULL;
181 //  shl_t handlesym=0 ;
182
183   errno = 0 ;
184   //  if (  shl_findsym( &handlesym,aName,TYPE_PROCEDURE,&adr_get) == -1 ) {
185   if ( shl_findsym((shl_t *)&myHandle,aName,TYPE_PROCEDURE,&adr_get) == -1 ) {
186     if ( errno != 0 )
187       perror("OSD_SharedLibrary : shl_findsym perror : ") ;
188     return (OSD_Function)NULL;
189   }
190   else return (OSD_Function) adr_get;
191 #endif
192
193 }
194 // ----------------------------------------------------------------
195 //
196 //DlClose: The dlclose function deallocates the address space for the library
197 //corresponding to handle.  If any user function continues to call a symbol
198 //resolved in the address space of a library that has been since been deallo-
199 //cated by dlclose, the results are undefined.
200 //
201 // ----------------------------------------------------------------
202 void OSD_SharedLibrary::DlClose()const{
203
204 #ifndef HAVE_DL_H
205  dlclose(myHandle);
206 #else
207  shl_unload((shl_t)myHandle);
208 #endif
209
210 }
211 // ----------------------------------------------------------------
212 //
213 // DlError:  returns a string   describing the last error that
214 // occurred from a call to dlopen, dlclose or dlsym.
215 //
216 // ----------------------------------------------------------------
217 Standard_CString OSD_SharedLibrary::DlError()const{
218 #ifndef HAVE_DL_H
219 return (char*) dlerror();
220 #else
221 perror("shl_load, shl_findsym, or shl_unload : perror : ") ;
222 return (char*) errno;
223 #endif
224 }
225 // ----------------------------------------------------------------------------
226 // Destroy
227 // ----------------------------------------------------------------------------
228 void OSD_SharedLibrary::Destroy() {
229   if (myName != NULL) {
230      delete [] myName;
231      myName = NULL;
232      myHandle = NULL;
233   }
234 }
235
236 #else
237
238 //------------------------------------------------------------------------
239 //-------------------  Windows NT sources for OSD_SharedLibrary ----------
240 //------------------------------------------------------------------------
241
242 //it is important to define STRICT and enforce including <windows.h> before
243 //Standard_Macro.hxx undefines it and includes <windows.h> causing compilation errors
244 #ifndef STRICT
245 #define STRICT
246 #endif
247 #include <windows.h>
248
249 #include <OSD_SharedLibrary.ixx>
250
251 #include <OSD_Path.hxx>
252
253 #include <TCollection_AsciiString.hxx>
254
255
256 static DWORD              lastDLLError;
257 static Standard_Character errMsg[ 1024 ];
258
259 OSD_SharedLibrary :: OSD_SharedLibrary () {
260
261  myHandle = NULL;
262  myName   = NULL;
263
264 }  // end constructor ( 1 )
265
266 OSD_SharedLibrary :: OSD_SharedLibrary ( const Standard_CString aFilename ) {
267
268  myHandle = NULL;
269  myName   = NULL;
270
271  SetName ( aFilename );
272
273 }  // end constructro ( 2 )
274
275 void OSD_SharedLibrary :: SetName ( const Standard_CString aName ) {
276
277  OSD_Path                path ( aName );
278  TCollection_AsciiString name ( aName );
279
280  if ( myName != NULL )
281
282   delete [] myName;
283
284  myName = new Standard_Character[ strlen ( aName ) + 1 ];
285
286  strcpy ( myName, aName );
287
288  name = path.Name ();
289  name.AssignCat (  path.Extension ()  );
290
291  myHandle = GetModuleHandle (  name.ToCString ()  );
292
293 }  // end OSD_SharedLibrary :: SetName
294
295 Standard_CString OSD_SharedLibrary :: Name () const {
296
297  return myName;
298
299 }  // end OSD_SharedLibrary :: Name
300
301 Standard_Boolean OSD_SharedLibrary :: DlOpen ( const OSD_LoadMode Mode ) {
302
303  Standard_Boolean retVal = Standard_True;
304
305  if (  (  myHandle ) == NULL &&
306        (  myHandle = ( HINSTANCE )LoadLibraryEx (
307                                    myName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH
308                                   )  ) == NULL
309  ) {
310  
311   lastDLLError = GetLastError ();
312   retVal       = Standard_False;
313  
314  }  // end if
315
316  return retVal;
317
318 }  // end OSD_SharedLibrary :: DlOpen
319
320 OSD_Function OSD_SharedLibrary :: DlSymb ( const Standard_CString Name ) const {
321
322  OSD_Function func = ( OSD_Function )GetProcAddress (  ( HMODULE )myHandle, Name  );
323
324  if ( func == NULL )
325
326   lastDLLError = GetLastError ();
327
328  return func;
329
330 }  // end OSD_SharedLibrary :: DlSymb
331
332 void OSD_SharedLibrary :: DlClose () const {
333
334  FreeLibrary (  ( HMODULE )myHandle  );
335
336 }  // end OSD_SharedLibrary :: DlClose
337
338 Standard_CString OSD_SharedLibrary :: DlError () const {
339
340  FormatMessage (
341   FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
342   0, lastDLLError, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), errMsg, 1024, ( va_list* )&myName
343  );
344
345  return errMsg;
346
347 }  // end OSD_SharedLibrary :: DlError
348
349 void OSD_SharedLibrary :: Destroy () {
350
351  if ( myName != NULL ) delete [] myName;
352
353 }  // end OSD_SharedLibrary :: Destroy
354
355 #endif