summaryrefslogtreecommitdiff
path: root/qmake/tools/qlibrary.cpp
Unidiff
Diffstat (limited to 'qmake/tools/qlibrary.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qlibrary.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/qmake/tools/qlibrary.cpp b/qmake/tools/qlibrary.cpp
new file mode 100644
index 0000000..564db30
--- a/dev/null
+++ b/qmake/tools/qlibrary.cpp
@@ -0,0 +1,343 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QLibrary class
5**
6** Created : 2000-01-01
7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39#include <private/qlibrary_p.h>
40
41#ifndef QT_NO_LIBRARY
42
43// uncomment this to get error messages
44//#define QT_DEBUG_COMPONENT 1
45// uncomment this to get error and success messages
46//#define QT_DEBUG_COMPONENT 2
47
48#ifndef QT_DEBUG_COMPONENT
49# if defined(QT_DEBUG)
50# define QT_DEBUG_COMPONENT 1
51# endif
52#endif
53
54#if defined(QT_DEBUG_COMPONENT)
55#include <qfile.h>
56#endif
57
58#if defined(Q_WS_WIN) && !defined(QT_MAKEDLL)
59#define QT_NO_LIBRARY_UNLOAD
60#endif
61
62QLibraryPrivate::QLibraryPrivate( QLibrary *lib )
63 : pHnd( 0 ), library( lib )
64{
65}
66
67
68/*!
69 \class QLibrary qlibrary.h
70 \reentrant
71 \brief The QLibrary class provides a wrapper for handling shared libraries.
72
73 \mainclass
74 \group plugins
75
76 An instance of a QLibrary object can handle a single shared
77 library and provide access to the functionality in the library in
78 a platform independent way. If the library is a component server,
79 QLibrary provides access to the exported component and can
80 directly query this component for interfaces.
81
82 QLibrary ensures that the shared library is loaded and stays in
83 memory whilst it is in use. QLibrary can also unload the library
84 on destruction and release unused resources.
85
86 A typical use of QLibrary is to resolve an exported symbol in a
87 shared object, and to call the function that this symbol
88 represents. This is called "explicit linking" in contrast to
89 "implicit linking", which is done by the link step in the build
90 process when linking an executable against a library.
91
92 The following code snippet loads a library, resolves the symbol
93 "mysymbol", and calls the function if everything succeeded. If
94 something went wrong, e.g. the library file does not exist or the
95 symbol is not defined, the function pointer will be 0 and won't be
96 called. When the QLibrary object is destroyed the library will be
97 unloaded, making all references to memory allocated in the library
98 invalid.
99
100 \code
101 typedef void (*MyPrototype)();
102 MyPrototype myFunction;
103
104 QLibrary myLib( "mylib" );
105 myFunction = (MyProtoype) myLib.resolve( "mysymbol" );
106 if ( myFunction ) {
107 myFunction();
108 }
109 \endcode
110*/
111
112/*!
113 Creates a QLibrary object for the shared library \a filename. The
114 library will be unloaded in the destructor.
115
116 Note that \a filename does not need to include the (platform specific)
117 file extension, so calling
118 \code
119 QLibrary lib( "mylib" );
120 \endcode
121 is equivalent to calling
122 \code
123 QLibrary lib( "mylib.dll" );
124 \endcode
125 on Windows, and
126 \code
127 QLibrary lib( "libmylib.so" );
128 \endcode
129 on Unix. Specifying the extension is not recommended, since
130 doing so introduces a platform dependency.
131
132 If \a filename does not include a path, the library loader will
133 look for the file in the platform specific search paths.
134
135 \sa load() unload(), setAutoUnload()
136*/
137QLibrary::QLibrary( const QString& filename )
138 : libfile( filename ), aunload( TRUE )
139{
140 libfile.replace( '\\', '/' );
141 d = new QLibraryPrivate( this );
142}
143
144/*!
145 Deletes the QLibrary object.
146
147 The library will be unloaded if autoUnload() is TRUE (the
148 default), otherwise it stays in memory until the application
149 exits.
150
151 \sa unload(), setAutoUnload()
152*/
153QLibrary::~QLibrary()
154{
155 if ( autoUnload() )
156 unload();
157
158 delete d;
159}
160
161/*!
162 Returns the address of the exported symbol \a symb. The library is
163 loaded if necessary. The function returns 0 if the symbol could
164 not be resolved or the library could not be loaded.
165
166 \code
167 typedef int (*avgProc)( int, int );
168
169 avgProc avg = (avgProc) library->resolve( "avg" );
170 if ( avg )
171 return avg( 5, 8 );
172 else
173 return -1;
174 \endcode
175
176*/
177void *QLibrary::resolve( const char* symb )
178{
179 if ( !d->pHnd )
180 load();
181 if ( !d->pHnd )
182 return 0;
183
184 void *address = d->resolveSymbol( symb );
185
186 return address;
187}
188
189/*!
190 \overload
191
192 Loads the library \a filename and returns the address of the
193 exported symbol \a symb. Note that like the constructor, \a
194 filename does not need to include the (platform specific) file
195 extension. The library remains loaded until the process exits.
196
197 The function returns 0 if the symbol could not be resolved or the
198 library could not be loaded.
199
200 This function is useful only if you want to resolve a single
201 symbol, e.g. a function pointer from a specific library once:
202
203 \code
204 typedef void (*FunctionType)();
205 static FunctionType *ptrFunction = 0;
206 static bool triedResolve = FALSE;
207 if ( !ptrFunction && !triedResolve )
208 ptrFunction = QLibrary::resolve( "mylib", "mysymb" );
209
210 if ( ptrFunction )
211 ptrFunction();
212 else
213 ...
214 \endcode
215
216 If you want to resolve multiple symbols, use a QLibrary object and
217 call the non-static version of resolve().
218
219 \sa resolve()
220*/
221void *QLibrary::resolve( const QString &filename, const char *symb )
222{
223 QLibrary lib( filename );
224 lib.setAutoUnload( FALSE );
225 return lib.resolve( symb );
226}
227
228/*!
229 Returns TRUE if the library is loaded; otherwise returns FALSE.
230
231 \sa unload()
232*/
233bool QLibrary::isLoaded() const
234{
235 return d->pHnd != 0;
236}
237
238/*!
239 Loads the library. Since resolve() always calls this function
240 before resolving any symbols it is not necessary to call it
241 explicitly. In some situations you might want the library loaded
242 in advance, in which case you would use this function.
243*/
244bool QLibrary::load()
245{
246 return d->loadLibrary();
247}
248
249/*!
250 Unloads the library and returns TRUE if the library could be
251 unloaded; otherwise returns FALSE.
252
253 This function is called by the destructor if autoUnload() is
254 enabled.
255
256 \sa resolve()
257*/
258bool QLibrary::unload()
259{
260 if ( !d->pHnd )
261 return TRUE;
262
263#if !defined(QT_NO_LIBRARY_UNLOAD)
264 if ( !d->freeLibrary() ) {
265# if defined(QT_DEBUG_COMPONENT)
266 qWarning( "%s could not be unloaded", (const char*) QFile::encodeName(library()) );
267# endif
268 return FALSE;
269 }
270
271# if defined(QT_DEBUG_COMPONENT) && QT_DEBUG_COMPONENT == 2
272 qWarning( "%s has been unloaded", (const char*) QFile::encodeName(library()) );
273# endif
274 d->pHnd = 0;
275#endif
276 return TRUE;
277}
278
279/*!
280 Returns TRUE if the library will be automatically unloaded when
281 this wrapper object is destructed; otherwise returns FALSE. The
282 default is TRUE.
283
284 \sa setAutoUnload()
285*/
286bool QLibrary::autoUnload() const
287{
288 return (bool)aunload;
289}
290
291/*!
292 If \a enabled is TRUE (the default), the wrapper object is set to
293 automatically unload the library upon destruction. If \a enabled
294 is FALSE, the wrapper object is not unloaded unless you explicitly
295 call unload().
296
297 \sa autoUnload()
298*/
299void QLibrary::setAutoUnload( bool enabled )
300{
301 aunload = enabled;
302}
303
304/*!
305 Returns the filename of the shared library this QLibrary object
306 handles, including the platform specific file extension.
307
308 For example:
309 \code
310 QLibrary lib( "mylib" );
311 QString str = lib.library();
312 \endcode
313 will set \e str to "mylib.dll" on Windows, and "libmylib.so" on Linux.
314*/
315QString QLibrary::library() const
316{
317 if ( libfile.isEmpty() )
318 return libfile;
319
320 QString filename = libfile;
321
322#if defined(Q_WS_WIN)
323 if ( filename.findRev( '.' ) <= filename.findRev( '/' ) )
324 filename += ".dll";
325#elif defined(Q_OS_MACX)
326 if ( filename.find( ".dylib" ) == -1 )
327 filename += ".dylib";
328#else
329 if ( filename.find( ".so" ) == -1 ) {
330 const int x = filename.findRev( "/" );
331 if ( x != -1 ) {
332 QString path = filename.left( x + 1 );
333 QString file = filename.right( filename.length() - x - 1 );
334 filename = QString( "%1lib%2.so" ).arg( path ).arg( file );
335 } else {
336 filename = QString( "lib%1.so" ).arg( filename );
337 }
338 }
339#endif
340
341 return filename;
342}
343#endif //QT_NO_LIBRARY