]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/dynlib.cpp
Misc. Dialog Editor/resource bugs fixed
[wxWidgets.git] / src / common / dynlib.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: dynlib.cpp
3// Purpose: Dynamic library management
4// Author: Guilhem Lavaux
5// Modified by:
6// Created: 20/07/98
7// RCS-ID: $Id$
8// Copyright: (c) Guilhem Lavaux
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21# pragma implementation "dynlib.h"
22#endif
23
24#include "wx/wxprec.h"
25#if defined(__WINDOWS__)
26#include "wx/msw/private.h"
27#endif
28
29#ifdef __BORLANDC__
30 #pragma hdrstop
31#endif
32#if wxUSE_DYNLIB_CLASS
33
34#include "wx/dynlib.h"
35#include "wx/filefn.h"
36#include "wx/intl.h"
37#include "wx/log.h"
38#include "wx/tokenzr.h"
39
40// ----------------------------------------------------------------------------
41// conditional compilation
42// ----------------------------------------------------------------------------
43
44#if defined(HAVE_DLOPEN)
45# define wxDllOpen(lib) dlopen(lib.fn_str(), RTLD_NOW/*RTLD_LAZY*/)
46# define wxDllGetSymbol(handle, name) dlsym(handle, name.mb_str())
47# define wxDllClose dlclose
48#elif defined(HAVE_SHL_LOAD)
49# define wxDllOpen(lib) shl_load(lib.fn_str(), BIND_DEFERRED, 0)
50# define wxDllClose shl_unload
51
52 static inline void *wxDllGetSymbol(shl_t handle, const wxString& name)
53 {
54 void *sym;
55 if ( shl_findsym(&handle, name.mb_str(), TYPE_UNDEFINED, &sym) == 0 )
56 return sym;
57 else
58 return (void *)0;
59 }
60#elif defined(__WINDOWS__)
61 // using LoadLibraryEx under Win32 to avoid name clash with LoadLibrary
62# ifdef __WIN32__
63# define wxDllOpen(lib) ::LoadLibraryEx(lib, 0, 0)
64# else // Win16
65# define wxDllOpen(lib) ::LoadLibrary(lib)
66# endif // Win32/16
67# define wxDllGetSymbol(handle, name) ::GetProcAddress(handle, name)
68# define wxDllClose ::FreeLibrary
69
70#elif defined(__OS2__)
71
72# define INCL_DOS
73# include <os2.h>
74# define wxDllOpen(error, lib, handle) DosLoadModule(error, sizeof(error), lib, &handle)
75# define wxDllGetSymbol(handle, modaddr) DosQueryProcAddr(handle, 1L, NULL, (PFN*)modaddr)
76# define wxDllClose(handle) DosFreeModule(handle)
77#else
78# error "Don't know how to load shared libraries on this platform."
79#endif // OS
80
81// ---------------------------------------------------------------------------
82// Global variables
83// ---------------------------------------------------------------------------
84
85wxLibraries wxTheLibraries;
86
87// ----------------------------------------------------------------------------
88// private functions
89// ----------------------------------------------------------------------------
90
91// construct the full name from the base shared object name: adds a .dll
92// suffix under Windows or .so under Unix
93static wxString ConstructLibraryName(const wxString& basename)
94{
95 wxString fullname(basename);
96
97#if defined(__UNIX__)
98# if defined(__HPUX__)
99 fullname << ".sl";
100# else //__HPUX__
101 fullname << ".so";
102# endif //__HPUX__
103#elif defined(__WINDOWS__) || defined(__OS2__)
104 fullname << ".dll";
105#endif
106
107 return fullname;
108}
109
110// ============================================================================
111// implementation
112// ============================================================================
113
114
115// ---------------------------------------------------------------------------
116// wxLibrary (one instance per dynamic library)
117// ---------------------------------------------------------------------------
118
119wxLibrary::wxLibrary(wxDllType handle)
120{
121 typedef wxClassInfo *(*t_get_first)(void);
122 t_get_first get_first;
123
124 m_handle = handle;
125
126 // Some system may use a local heap for library.
127 get_first = (t_get_first)GetSymbol("wxGetClassFirst");
128 // It is a wxWindows DLL.
129 if (get_first)
130 PrepareClasses(get_first());
131}
132
133wxLibrary::~wxLibrary()
134{
135 if ( m_handle )
136 {
137 wxDllClose(m_handle);
138 }
139}
140
141wxObject *wxLibrary::CreateObject(const wxString& name)
142{
143 wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
144
145 if (!info)
146 return NULL;
147
148 return info->CreateObject();
149}
150
151void wxLibrary::PrepareClasses(wxClassInfo *first)
152{
153 // Index all class infos by their class name
154 wxClassInfo *info = first;
155 while (info)
156 {
157 if (info->m_className)
158 classTable.Put(info->m_className, (wxObject *)info);
159 info = info->GetNext();
160 }
161
162 // Set base pointers for each wxClassInfo
163 info = first;
164 while (info)
165 {
166 if (info->GetBaseClassName1())
167 info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
168 if (info->GetBaseClassName2())
169 info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
170 info = info->m_next;
171 }
172}
173
174void *wxLibrary::GetSymbol(const wxString& symbname)
175{
176 return wxDllLoader::GetSymbol(m_handle, symbname);
177}
178
179// ---------------------------------------------------------------------------
180// wxDllLoader
181// ---------------------------------------------------------------------------
182
183/* static */
184wxDllType
185wxDllLoader::GetProgramHandle(void)
186{
187#if defined( HAVE_DLOPEN )
188 // optain handle for main program
189 return dlopen(NULL, RTLD_NOW/*RTLD_LAZY*/);
190#elif defined (HAVE_SHL_LOAD)
191 // shl_findsymbol with NULL handle looks up in main program
192 return 0;
193#else
194 wxFAIL_MSG( wxT("This method is not implemented under Windows or OS/2"));
195 return 0;
196#endif
197}
198
199/* static */
200wxDllType
201wxDllLoader::LoadLibrary(const wxString & libname, bool *success)
202{
203 wxDllType handle;
204
205#if defined(__WXMAC__)
206 FSSpec myFSSpec ;
207 Ptr myMainAddr ;
208 Str255 myErrName ;
209
210 wxMacPathToFSSpec( libname , &myFSSpec ) ;
211 if (GetDiskFragment( &myFSSpec , 0 , kCFragGoesToEOF , "\p" , kPrivateCFragCopy , &handle , &myMainAddr ,
212 myErrName ) != noErr )
213 {
214 p2cstr( myErrName ) ;
215 wxASSERT_MSG( 1 , (char*)myErrName ) ;
216 return NULL ;
217 }
218#elif defined(__OS2__)
219 char zError[256] = "";
220 wxDllOpen(zError, libname, handle);
221#else // !Mac
222 handle = wxDllOpen(libname);
223#endif // OS
224
225 if ( !handle )
226 {
227 wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
228 }
229
230 if ( success )
231 {
232 *success = handle != 0;
233 }
234
235 return handle;
236}
237
238
239/* static */
240void
241wxDllLoader::UnloadLibrary(wxDllType handle)
242{
243 wxDllClose(handle);
244}
245
246/* static */
247void *
248wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name)
249{
250 void *symbol = NULL; // return value
251
252#if defined( __WXMAC__ )
253 Ptr symAddress ;
254 CFragSymbolClass symClass ;
255 Str255 symName ;
256
257 strcpy( (char*) symName , name ) ;
258 c2pstr( (char*) symName ) ;
259
260 if ( FindSymbol( dllHandle , symName , &symAddress , &symClass ) == noErr )
261 symbol = (void *)symAddress ;
262#elif defined( __OS2__ )
263 wxDllGetSymbol(dllHandle, symbol);
264#else
265 symbol = wxDllGetSymbol(dllHandle, name);
266#endif
267
268 if ( !symbol )
269 {
270 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
271 name.c_str());
272 }
273 return symbol;
274}
275
276// ---------------------------------------------------------------------------
277// wxLibraries (only one instance should normally exist)
278// ---------------------------------------------------------------------------
279
280wxLibraries::wxLibraries():m_loaded(wxKEY_STRING)
281{
282}
283
284wxLibraries::~wxLibraries()
285{
286 wxNode *node = m_loaded.First();
287
288 while (node) {
289 wxLibrary *lib = (wxLibrary *)node->Data();
290 delete lib;
291
292 node = node->Next();
293 }
294}
295
296wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
297{
298 wxNode *node;
299 wxLibrary *lib;
300 wxClassInfo *old_sm_first;
301
302#if defined(__VISAGECPP__)
303 node = m_loaded.Find(name.GetData());
304 if (node != NULL)
305 return ((wxLibrary *)node->Data());
306#else // !OS/2
307 if ( (node = m_loaded.Find(name.GetData())) )
308 return ((wxLibrary *)node->Data());
309#endif
310 // If DLL shares data, this is necessary.
311 old_sm_first = wxClassInfo::sm_first;
312 wxClassInfo::sm_first = NULL;
313
314 wxString libname = ConstructLibraryName(name);
315
316/*
317 Unix automatically builds that library name, at least for dlopen()
318*/
319#if 0
320#if defined(__UNIX__)
321 // found the first file in LD_LIBRARY_PATH with this name
322 wxString libPath("/lib:/usr/lib"); // system path first
323 const char *envLibPath = getenv("LD_LIBRARY_PATH");
324 if ( envLibPath )
325 libPath << wxT(':') << envLibPath;
326 wxStringTokenizer tokenizer(libPath, wxT(':'));
327 while ( tokenizer.HasMoreToken() )
328 {
329 wxString fullname(tokenizer.NextToken());
330
331 fullname << wxT('/') << libname;
332 if ( wxFileExists(fullname) )
333 {
334 libname = fullname;
335
336 // found the library
337 break;
338 }
339 }
340 //else: not found in the path, leave the name as is (secutiry risk?)
341
342#endif // __UNIX__
343#endif
344
345 bool success = FALSE;
346 wxDllType handle = wxDllLoader::LoadLibrary(libname, &success);
347 if(success)
348 {
349 lib = new wxLibrary(handle);
350 wxClassInfo::sm_first = old_sm_first;
351 m_loaded.Append(name.GetData(), lib);
352 }
353 else
354 lib = NULL;
355 return lib;
356}
357
358wxObject *wxLibraries::CreateObject(const wxString& path)
359{
360 wxNode *node = m_loaded.First();
361 wxObject *obj;
362
363 while (node) {
364 obj = ((wxLibrary *)node->Data())->CreateObject(path);
365 if (obj)
366 return obj;
367
368 node = node->Next();
369 }
370 return NULL;
371}
372
373#endif // wxUSE_DYNLIB_CLASS