1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
18 #include <OSD_Function.hxx>
19 #include <OSD_LoadMode.hxx>
20 #include <OSD_SharedLibrary.hxx>
23 #ifdef __some_crappy_system__
25 * Values for 'mode' argument in dlopen().
31 * Interface to rld via unsupported __rld_libdl_interface() call.
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);}
46 #define BAD(X) ((X) == NULL)
48 // ----------------------------------------------------------------
50 // Create and initialize a shared library object to NULL
52 // ----------------------------------------------------------------
53 OSD_SharedLibrary::OSD_SharedLibrary():myHandle(NULL),myName(NULL){
55 // ----------------------------------------------------------------
57 // Create and initialize a shared library object to the
58 // name given as argument
60 // ----------------------------------------------------------------
61 OSD_SharedLibrary::OSD_SharedLibrary(const Standard_CString aName):myHandle(NULL)
64 myName = new char [(strlen (aName) + 1 )];
65 strcpy (myName,aName);
68 // ----------------------------------------------------------------
70 // Name: Returns the shared library name
72 // ----------------------------------------------------------------
73 Standard_CString OSD_SharedLibrary::Name() const {
76 // ----------------------------------------------------------------
78 // SetName: Sets a name to a shared library object
80 // ----------------------------------------------------------------
81 void OSD_SharedLibrary::SetName(const Standard_CString aName) {
83 myName = new char [(strlen (aName) + 1 )];
84 strcpy (myName,aName);
87 // ----------------------------------------------------------------
89 // DlOpen: The dlopen function provides an interface to the dynamic
90 // library loader to allow shared libraries to be loaded and called at
92 // The dlopen function attempts to load filename, in the address space
93 // of the process, resolving symbols as appropriate. Any libraries that
94 // filename depends upon are also loaded.
96 // If mode is RTLD_LAZY, then the runtime loader does symbol resolution
97 // only as needed. Typically, this means that the first call
98 // to a function in the newly loaded library will cause the resolution
99 // of the address of that function to occur.
101 // If mode is RTLD_NOW, then the runtime loader must do all
102 // symbol binding during the dlopen call.
103 // The dlopen function returns a handle that is used by dlsym or
104 // dlclose call. If there is an error, a NULLpointer is returned.
106 // If a NULL filename is specified, dlopen returns a handle for the main
107 // executable, which allows access to dynamic symbols in the running program.
109 // ----------------------------------------------------------------
110 Standard_Boolean OSD_SharedLibrary::DlOpen(const OSD_LoadMode aMode ) {
111 if (aMode == OSD_RTLD_LAZY){
112 myHandle = dlopen (myName,RTLD_LAZY);
114 else if (aMode == OSD_RTLD_NOW){
115 myHandle = dlopen (myName,RTLD_NOW);
119 return Standard_True;
122 return Standard_False;
125 // ----------------------------------------------------------------
127 // DlSymb: The dlsym function returns the address of the
128 // symbol name found in the shared library corresponding to handle.
129 // If the symbol is not found, a NULL
130 // pointer is returned.
132 // ----------------------------------------------------------------
133 OSD_Function OSD_SharedLibrary::DlSymb(const Standard_CString aName )const{
135 fp = (void (*)()) dlsym (myHandle,aName);
137 return (OSD_Function)fp;
140 return (OSD_Function)NULL;
143 // ----------------------------------------------------------------
145 //DlClose: The dlclose function deallocates the address space for the library
146 //corresponding to handle. If any user function continues to call a symbol
147 //resolved in the address space of a library that has been since been deallo-
148 //cated by dlclose, the results are undefined.
150 // ----------------------------------------------------------------
151 void OSD_SharedLibrary::DlClose()const{
154 // ----------------------------------------------------------------
156 // DlError: returns a string describing the last error that
157 // occurred from a call to dlopen, dlclose or dlsym.
159 // ----------------------------------------------------------------
160 Standard_CString OSD_SharedLibrary::DlError()const{
161 return (char*) dlerror();
163 // ----------------------------------------------------------------------------
165 // ----------------------------------------------------------------------------
166 void OSD_SharedLibrary::Destroy() {
167 if (myName != NULL) {
176 //------------------------------------------------------------------------
177 //------------------- Windows NT sources for OSD_SharedLibrary ----------
178 //------------------------------------------------------------------------
180 //it is important to define STRICT and enforce including <windows.h> before
181 //Standard_Macro.hxx undefines it and includes <windows.h> causing compilation errors
187 #include <OSD_Path.hxx>
188 #include <OSD_SharedLibrary.hxx>
189 #include <TCollection_AsciiString.hxx>
190 #include <TCollection_ExtendedString.hxx>
192 static DWORD lastDLLError;
194 static wchar_t errMsg[1024];
195 static char errMsgA[1024];
197 OSD_SharedLibrary :: OSD_SharedLibrary () {
202 } // end constructor ( 1 )
204 OSD_SharedLibrary :: OSD_SharedLibrary ( const Standard_CString aFilename ) {
209 SetName ( aFilename );
211 } // end constructro ( 2 )
213 void OSD_SharedLibrary :: SetName ( const Standard_CString aName ) {
215 OSD_Path path ( aName );
216 TCollection_AsciiString name ( aName );
218 if ( myName != NULL )
222 myName = new Standard_Character[ strlen ( aName ) + 1 ];
224 strcpy ( myName, aName );
227 name.AssignCat ( path.Extension () );
230 myHandle = GetModuleHandle(name.ToCString());
232 TCollection_ExtendedString nameW(name);
233 myHandle = LoadPackagedLibrary ((const wchar_t*)nameW.ToExtString(), NULL );
234 FreeLibrary ((HMODULE) myHandle);
237 } // end OSD_SharedLibrary :: SetName
239 Standard_CString OSD_SharedLibrary :: Name () const {
243 } // end OSD_SharedLibrary :: Name
245 Standard_Boolean OSD_SharedLibrary :: DlOpen ( const OSD_LoadMode /*Mode*/ ) {
247 Standard_Boolean retVal = Standard_True;
249 if ( myHandle == NULL ) {
251 myHandle = (HINSTANCE)LoadLibraryEx(myName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
253 TCollection_ExtendedString myNameW(myName);
254 myHandle = (HINSTANCE)LoadPackagedLibrary((const wchar_t*)myNameW.ToExtString(), NULL);
256 if ( myHandle == NULL ) {
257 lastDLLError = GetLastError ();
258 retVal = Standard_False;
264 } // end OSD_SharedLibrary :: DlOpen
266 OSD_Function OSD_SharedLibrary :: DlSymb ( const Standard_CString Name ) const {
268 OSD_Function func = ( OSD_Function )GetProcAddress ( ( HMODULE )myHandle, Name );
272 lastDLLError = GetLastError ();
276 } // end OSD_SharedLibrary :: DlSymb
278 void OSD_SharedLibrary :: DlClose () const {
280 FreeLibrary ( ( HMODULE )myHandle );
282 } // end OSD_SharedLibrary :: DlClose
284 Standard_CString OSD_SharedLibrary :: DlError () const {
287 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
288 0, lastDLLError, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
289 errMsg, 1024, ( va_list* )&myName
292 WideCharToMultiByte(CP_UTF8, 0, errMsg, -1, errMsgA, sizeof(errMsgA), NULL, NULL);
294 } // end OSD_SharedLibrary :: DlError
296 void OSD_SharedLibrary :: Destroy () {
298 if ( myName != NULL ) delete [] myName;
300 } // end OSD_SharedLibrary :: Destroy