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