1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
26 #include <OSD_LoadMode.hxx>
27 #include <OSD_SharedLibrary.ixx>
28 #include <OSD_Function.hxx>
36 #ifdef __some_crappy_system__
38 * Values for 'mode' argument in dlopen().
44 * Interface to rld via unsupported __rld_libdl_interface() call.
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);}
65 extern "C" {size_t strlen (const char* s );}
68 #define BAD(X) ((X) == NULL)
70 // ----------------------------------------------------------------
72 // Create and initialize a shared library object to NULL
74 // ----------------------------------------------------------------
75 OSD_SharedLibrary::OSD_SharedLibrary():myHandle(NULL),myName(NULL){
77 // ----------------------------------------------------------------
79 // Create and initialize a shared library object to the
80 // name given as argument
82 // ----------------------------------------------------------------
83 OSD_SharedLibrary::OSD_SharedLibrary(const Standard_CString aName):myHandle(NULL)
86 myName = new char [(strlen (aName) + 1 )];
87 strcpy (myName,aName);
90 // ----------------------------------------------------------------
92 // Name: Returns the shared library name
94 // ----------------------------------------------------------------
95 Standard_CString OSD_SharedLibrary::Name() const {
98 // ----------------------------------------------------------------
100 // SetName: Sets a name to a shared library object
102 // ----------------------------------------------------------------
103 void OSD_SharedLibrary::SetName(const Standard_CString aName) {
105 myName = new char [(strlen (aName) + 1 )];
106 strcpy (myName,aName);
109 // ----------------------------------------------------------------
111 // DlOpen: The dlopen function provides an interface to the dynamic
112 // library loader to allow shared libraries to be loaded and called at
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.
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.
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.
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.
131 // ----------------------------------------------------------------
132 Standard_Boolean OSD_SharedLibrary::DlOpen(const OSD_LoadMode aMode ) {
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);
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);
145 if (aMode == OSD_RTLD_LAZY){
146 myHandle = dlopen (myName,RTLD_LAZY);
148 else if (aMode == OSD_RTLD_NOW){
149 myHandle = dlopen (myName,RTLD_NOW);
154 return Standard_True;
157 return Standard_False;
160 // ----------------------------------------------------------------
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.
167 // ----------------------------------------------------------------
168 OSD_Function OSD_SharedLibrary::DlSymb(const Standard_CString aName )const{
172 fp = (void (*)()) dlsym (myHandle,aName);
174 return (OSD_Function)fp;
177 return (OSD_Function)NULL;
180 void *adr_get = NULL;
181 // shl_t handlesym=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 ) {
187 perror("OSD_SharedLibrary : shl_findsym perror : ") ;
188 return (OSD_Function)NULL;
190 else return (OSD_Function) adr_get;
194 // ----------------------------------------------------------------
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.
201 // ----------------------------------------------------------------
202 void OSD_SharedLibrary::DlClose()const{
207 shl_unload((shl_t)myHandle);
211 // ----------------------------------------------------------------
213 // DlError: returns a string describing the last error that
214 // occurred from a call to dlopen, dlclose or dlsym.
216 // ----------------------------------------------------------------
217 Standard_CString OSD_SharedLibrary::DlError()const{
219 return (char*) dlerror();
221 perror("shl_load, shl_findsym, or shl_unload : perror : ") ;
222 return (char*) errno;
225 // ----------------------------------------------------------------------------
227 // ----------------------------------------------------------------------------
228 void OSD_SharedLibrary::Destroy() {
229 if (myName != NULL) {
238 //------------------------------------------------------------------------
239 //------------------- Windows NT sources for OSD_SharedLibrary ----------
240 //------------------------------------------------------------------------
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
249 #include <OSD_SharedLibrary.ixx>
251 #include <OSD_Path.hxx>
253 #include <TCollection_AsciiString.hxx>
256 static DWORD lastDLLError;
257 static Standard_Character errMsg[ 1024 ];
259 OSD_SharedLibrary :: OSD_SharedLibrary () {
264 } // end constructor ( 1 )
266 OSD_SharedLibrary :: OSD_SharedLibrary ( const Standard_CString aFilename ) {
271 SetName ( aFilename );
273 } // end constructro ( 2 )
275 void OSD_SharedLibrary :: SetName ( const Standard_CString aName ) {
277 OSD_Path path ( aName );
278 TCollection_AsciiString name ( aName );
280 if ( myName != NULL )
284 myName = new Standard_Character[ strlen ( aName ) + 1 ];
286 strcpy ( myName, aName );
289 name.AssignCat ( path.Extension () );
291 myHandle = GetModuleHandle ( name.ToCString () );
293 } // end OSD_SharedLibrary :: SetName
295 Standard_CString OSD_SharedLibrary :: Name () const {
299 } // end OSD_SharedLibrary :: Name
301 Standard_Boolean OSD_SharedLibrary :: DlOpen ( const OSD_LoadMode Mode ) {
303 Standard_Boolean retVal = Standard_True;
305 if ( ( myHandle ) == NULL &&
306 ( myHandle = ( HINSTANCE )LoadLibraryEx (
307 myName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH
311 lastDLLError = GetLastError ();
312 retVal = Standard_False;
318 } // end OSD_SharedLibrary :: DlOpen
320 OSD_Function OSD_SharedLibrary :: DlSymb ( const Standard_CString Name ) const {
322 OSD_Function func = ( OSD_Function )GetProcAddress ( ( HMODULE )myHandle, Name );
326 lastDLLError = GetLastError ();
330 } // end OSD_SharedLibrary :: DlSymb
332 void OSD_SharedLibrary :: DlClose () const {
334 FreeLibrary ( ( HMODULE )myHandle );
336 } // end OSD_SharedLibrary :: DlClose
338 Standard_CString OSD_SharedLibrary :: DlError () const {
341 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
342 0, lastDLLError, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ), errMsg, 1024, ( va_list* )&myName
347 } // end OSD_SharedLibrary :: DlError
349 void OSD_SharedLibrary :: Destroy () {
351 if ( myName != NULL ) delete [] myName;
353 } // end OSD_SharedLibrary :: Destroy