1 /////////////////////////////////////////////////////////////////////////////
2 // Name: unix/dlunix.cpp
3 // Purpose: Unix-specific part of wxDynamicLibrary and related classes
4 // Author: Vadim Zeitlin
6 // Created: 2005-01-16 (extracted from common/dynlib.cpp)
8 // Copyright: (c) 2000-2005 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
26 #if wxUSE_DYNLIB_CLASS
28 #include "wx/dynlib.h"
30 #if defined(HAVE_DLOPEN) || defined(__DARWIN__)
31 #define USE_POSIX_DL_FUNCS
32 #elif !defined(HAVE_SHL_LOAD)
33 #error "Don't know how to load dynamic libraries on this platform!"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 // standard shared libraries extensions for different Unix versions
42 const wxChar
*wxDynamicLibrary::ms_dllext
= _T(".sl");
43 #elif defined(__DARWIN__)
44 const wxChar
*wxDynamicLibrary::ms_dllext
= _T(".bundle");
46 const wxChar
*wxDynamicLibrary::ms_dllext
= _T(".so");
49 // ============================================================================
50 // wxDynamicLibrary implementation
51 // ============================================================================
53 // ----------------------------------------------------------------------------
54 // dlxxx() emulation for Darwin
55 // ----------------------------------------------------------------------------
57 #if defined(__DARWIN__)
58 // ---------------------------------------------------------------------------
59 // For Darwin/Mac OS X
60 // supply the sun style dlopen functions in terms of Darwin NS*
61 // ---------------------------------------------------------------------------
64 * The dlopen port is a port from dl_next.xs by Anno Siegel.
65 * dl_next.xs is itself a port from dl_dlopen.xs by Paul Marquess.
66 * The method used here is just to supply the sun style dlopen etc.
67 * functions in terms of Darwin NS*.
71 #include <mach-o/dyld.h>
73 static char dl_last_error
[1024];
76 void TranslateError(const char *path
, int number
)
79 static char *OFIErrorStrings
[] =
81 "%s(%d): Object Image Load Failure\n",
82 "%s(%d): Object Image Load Success\n",
83 "%s(%d): Not an recognisable object file\n",
84 "%s(%d): No valid architecture\n",
85 "%s(%d): Object image has an invalid format\n",
86 "%s(%d): Invalid access (permissions?)\n",
87 "%s(%d): Unknown error code from NSCreateObjectFileImageFromFile\n",
89 #define NUM_OFI_ERRORS (sizeof(OFIErrorStrings) / sizeof(OFIErrorStrings[0]))
92 if (index
> NUM_OFI_ERRORS
- 1) {
93 index
= NUM_OFI_ERRORS
- 1;
95 sprintf(dl_last_error
, OFIErrorStrings
[index
], path
, number
);
100 return dl_last_error
;
103 void *dlopen(const char *path
, int WXUNUSED(mode
) /* mode is ignored */)
105 NSObjectFileImage ofile
;
106 NSModule handle
= NULL
;
108 int dyld_result
= NSCreateObjectFileImageFromFile(path
, &ofile
);
109 if ( dyld_result
!= NSObjectFileImageSuccess
)
115 handle
= NSLinkModule
119 NSLINKMODULE_OPTION_BINDNOW
|
120 NSLINKMODULE_OPTION_RETURN_ON_ERROR
125 TranslateError(path
, dyld_result
);
130 int dlclose(void *handle
)
132 NSUnLinkModule( handle
, NSUNLINKMODULE_OPTION_NONE
);
136 void *dlsym(void *handle
, const char *symbol
)
138 // as on many other systems, C symbols have prepended underscores under
139 // Darwin but unlike the normal dlopen(), NSLookupSymbolInModule() is not
141 wxCharBuffer
buf(strlen(symbol
) + 1);
142 char *p
= buf
.data();
144 strcpy(p
+ 1, symbol
);
146 NSSymbol nsSymbol
= NSLookupSymbolInModule( handle
, p
);
147 return nsSymbol
? NSAddressOfSymbol(nsSymbol
) : NULL
;
150 #endif // defined(__DARWIN__)
152 // ----------------------------------------------------------------------------
153 // loading/unloading DLLs
154 // ----------------------------------------------------------------------------
156 wxDllType
wxDynamicLibrary::GetProgramHandle()
158 #ifdef USE_POSIX_DL_FUNCS
159 return dlopen(0, RTLD_LAZY
);
166 wxDllType
wxDynamicLibrary::RawLoad(const wxString
& libname
, int flags
)
168 wxASSERT_MSG( (flags
& wxDL_NOW
) == 0,
169 _T("wxDL_LAZY and wxDL_NOW are mutually exclusive.") );
171 #ifdef USE_POSIX_DL_FUNCS
175 if ( flags
& wxDL_LAZY
)
177 rtldFlags
|= RTLD_LAZY
;
181 if ( flags
& wxDL_NOW
)
183 rtldFlags
|= RTLD_NOW
;
187 if ( flags
& wxDL_GLOBAL
)
189 rtldFlags
|= RTLD_GLOBAL
;
193 return dlopen(libname
.fn_str(), rtldFlags
);
194 #else // !USE_POSIX_DL_FUNCS
197 if ( flags
& wxDL_LAZY
)
199 shlFlags
|= BIND_DEFERRED
;
201 else if ( flags
& wxDL_NOW
)
203 shlFlags
|= BIND_IMMEDIATE
;
206 return shl_load(libname
.fn_str(), shlFlags
, 0);
207 #endif // USE_POSIX_DL_FUNCS/!USE_POSIX_DL_FUNCS
211 void wxDynamicLibrary::Unload(wxDllType handle
)
213 #ifdef wxHAVE_DYNLIB_ERROR
217 #ifdef USE_POSIX_DL_FUNCS
219 #else // !USE_POSIX_DL_FUNCS
221 #endif // USE_POSIX_DL_FUNCS/!USE_POSIX_DL_FUNCS
223 #ifdef USE_POSIX_DL_FUNCS
230 void *wxDynamicLibrary::RawGetSymbol(wxDllType handle
, const wxString
& name
)
234 #ifdef USE_POSIX_DL_FUNCS
235 symbol
= dlsym(handle
, name
.fn_str());
236 #else // !USE_POSIX_DL_FUNCS
237 // note that shl_findsym modifies the handle argument to indicate where the
238 // symbol was found, but it's ok to modify the local handle copy here
239 if ( shl_findsym(&handle
, name
.fn_str(), TYPE_UNDEFINED
, &symbol
) != 0 )
241 #endif // USE_POSIX_DL_FUNCS/!USE_POSIX_DL_FUNCS
246 #ifdef wxHAVE_DYNLIB_ERROR
249 void wxDynamicLibrary::Error()
252 wxWCharBuffer buffer
= wxConvLocal
.cMB2WC( dlerror() );
253 const wxChar
*err
= buffer
;
255 const wxChar
*err
= dlerror();
258 wxLogError(wxT("%s"), err
? err
: _("Unknown dynamic library error"));
261 #endif // wxHAVE_DYNLIB_ERROR
263 #endif // wxUSE_DYNLIB_CLASS