author | zautrix <zautrix> | 2004-06-26 19:01:18 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-06-26 19:01:18 (UTC) |
commit | b9aad1f15dc600e4dbe4c62d3fcced6363188ba3 (patch) (unidiff) | |
tree | 2c3d4004fb21c72cba65793859f9bcd8ffd3a49c /microkde/kdecore/klibloader.h | |
download | kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.zip kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.gz kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.bz2 |
Initial revision
Diffstat (limited to 'microkde/kdecore/klibloader.h') (more/less context) (ignore whitespace changes)
-rw-r--r-- | microkde/kdecore/klibloader.h | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/microkde/kdecore/klibloader.h b/microkde/kdecore/klibloader.h new file mode 100644 index 0000000..ed57109 --- a/dev/null +++ b/microkde/kdecore/klibloader.h | |||
@@ -0,0 +1,405 @@ | |||
1 | /* This file is part of the KDE libraries | ||
2 | Copyright (C) 1999 Torben Weis <weis@kde.org> | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Library General Public | ||
6 | License version 2 as published by the Free Software Foundation. | ||
7 | |||
8 | This library is distributed in the hope that it will be useful, | ||
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | Library General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU Library General Public License | ||
14 | along with this library; see the file COPYING.LIB. If not, write to | ||
15 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16 | Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | #ifndef KLIBLOADER_H | ||
19 | #define KLIBLOADER_H | ||
20 | |||
21 | #include <qobject.h> | ||
22 | #include <qstring.h> | ||
23 | #include <qstringlist.h> | ||
24 | #include <qasciidict.h> | ||
25 | #include <qptrlist.h> | ||
26 | #include <kglobal.h> | ||
27 | |||
28 | #include <stdlib.h> // For backwards compatibility | ||
29 | |||
30 | class KInstance; | ||
31 | class QTimer; | ||
32 | class KLibrary; | ||
33 | class KLibFactory; | ||
34 | class KLibFactoryPrivate; | ||
35 | class KLibLoaderPrivate; | ||
36 | class KLibraryPrivate; | ||
37 | |||
38 | class QLibrary; | ||
39 | |||
40 | #define K_EXPORT_COMPONENT_FACTORY( libname, factory ) \ | ||
41 | extern "C" { void *init_##libname() { return new factory; } } | ||
42 | |||
43 | /** | ||
44 | * @short Represents a dynamically loaded library. | ||
45 | * | ||
46 | * KLibrary allows you to look up symbols of the shared library. | ||
47 | * Use @ref KLibLoader to create a new instance of KLibrary. | ||
48 | * | ||
49 | * @see KLibLoader | ||
50 | * @author Torben Weis <weis@kde.org> | ||
51 | */ | ||
52 | class KLibrary : public QObject | ||
53 | { | ||
54 | friend class KLibLoader; | ||
55 | friend class QAsciiDict<KLibrary>; | ||
56 | |||
57 | Q_OBJECT | ||
58 | public: | ||
59 | /** | ||
60 | * @internal | ||
61 | * Don't create KLibrary objects on your own. Instead use @ref KLibLoader. | ||
62 | */ | ||
63 | //US KLibrary( const QString& libname, const QString& filename, void * handle ); | ||
64 | KLibrary( const QString& libname, const QString& filename, QLibrary* handle ); | ||
65 | |||
66 | /** | ||
67 | * Returns the name of the library. | ||
68 | * @return The name of the library like "libkspread". | ||
69 | */ | ||
70 | QString name() const; | ||
71 | |||
72 | /** | ||
73 | * Returns the file name of the library. | ||
74 | * @return The filename of the library, for example "/opt/kde2&/lib/libkspread.la" | ||
75 | */ | ||
76 | QString fileName() const; | ||
77 | |||
78 | /** | ||
79 | * Returns the factory of the library. | ||
80 | * @return The factory of the library if there is any, otherwise 0 | ||
81 | */ | ||
82 | KLibFactory* factory(); | ||
83 | |||
84 | /** | ||
85 | * Looks up a symbol from the library. This is a very low level | ||
86 | * function that you usually don't want to use. Usually you should | ||
87 | * check using @ref hasSymbol() whether the symbol actually exists, | ||
88 | * otherwise a warning will be printed. | ||
89 | * @param name the name of the symbol to look up | ||
90 | * @return the address of the symbol, or 0 if it does not exist | ||
91 | * @see #hasSymbol | ||
92 | */ | ||
93 | void* symbol( const char* name ) const; | ||
94 | |||
95 | /** | ||
96 | * Looks up a symbol from the library. This is a very low level | ||
97 | * function that you usually don't want to use. | ||
98 | * Unlike @ref symbol(), this method doesn't warn if the symbol doesn't exist, | ||
99 | * so if the symbol might or might not exist, better use hasSymbol() before symbol(). | ||
100 | * @param name the name of the symbol to check | ||
101 | * @return true if the symbol exists | ||
102 | * @since 3.1 | ||
103 | */ | ||
104 | bool hasSymbol( const char* name ) const; | ||
105 | |||
106 | /** | ||
107 | * Unloads the library. | ||
108 | * This typically results in the deletion of this object. You should | ||
109 | * not reference its pointer after calling this function. | ||
110 | */ | ||
111 | void unload() const; | ||
112 | |||
113 | private slots: | ||
114 | void slotObjectCreated( QObject *obj ); | ||
115 | void slotObjectDestroyed(); | ||
116 | void slotTimeout(); | ||
117 | |||
118 | private: | ||
119 | /** | ||
120 | * @internal | ||
121 | * Don't destruct KLibrary objects yourself. Instead use @ref unload() instead. | ||
122 | */ | ||
123 | ~KLibrary(); | ||
124 | |||
125 | QString m_libname; | ||
126 | QString m_filename; | ||
127 | KLibFactory* m_factory; | ||
128 | //US void * m_handle; | ||
129 | QLibrary* m_handle; | ||
130 | QPtrList<QObject> m_objs; | ||
131 | QTimer *m_timer; | ||
132 | KLibraryPrivate *d; | ||
133 | }; | ||
134 | |||
135 | class KLibWrapPrivate; | ||
136 | |||
137 | /** | ||
138 | * The KLibLoader allows you to load libraries dynamically at runtime. | ||
139 | * Dependent libraries are loaded automatically. | ||
140 | * | ||
141 | * KLibLoader follows the singleton pattern. You can not create multiple | ||
142 | * instances. Use @ref self() to get a pointer to the loader. | ||
143 | * | ||
144 | * @see KLibrary | ||
145 | * @author Torben Weis <weis@kde.org> | ||
146 | */ | ||
147 | class KLibLoader : public QObject | ||
148 | { | ||
149 | friend class KLibrary; | ||
150 | |||
151 | Q_OBJECT | ||
152 | public: | ||
153 | /** | ||
154 | * You should NEVER destruct an instance of KLibLoader | ||
155 | * until you know what you are doing. This will release | ||
156 | * the loaded libraries. | ||
157 | */ | ||
158 | ~KLibLoader(); | ||
159 | |||
160 | /** | ||
161 | * Loads and initializes a library. Loading a library multiple times is | ||
162 | * handled gracefully. | ||
163 | * | ||
164 | * This is a convenience function that returns the factory immediately | ||
165 | * @param libname This is the library name without extension. Usually that is something like | ||
166 | * "libkspread". The function will then search for a file named | ||
167 | * "libkspread.la" in the KDE library paths. | ||
168 | * The *.la files are created by libtool and contain | ||
169 | * important information especially about the libraries dependencies | ||
170 | * on other shared libs. Loading a "libfoo.so" could not solve the | ||
171 | * dependencies problem. | ||
172 | * | ||
173 | * You can, however, give a library name ending in ".so" | ||
174 | * (or whatever is used on your platform), and the library | ||
175 | * will be loaded without resolving dependencies. USE WITH CARE :) | ||
176 | * @return the @ref KLibFactory, or 0 if the library does not exist or it does | ||
177 | * not have a factory | ||
178 | * @see #library | ||
179 | */ | ||
180 | KLibFactory* factory( const char* libname ); | ||
181 | |||
182 | /** | ||
183 | * Loads and initializes a library. Loading a library multiple times is | ||
184 | * handled gracefully. | ||
185 | * | ||
186 | * @param libname This is the library name without extension. Usually that is something like | ||
187 | * "libkspread". The function will then search for a file named | ||
188 | * "libkspread.la" in the KDE library paths. | ||
189 | * The *.la files are created by libtool and contain | ||
190 | * important information especially about the libraries dependencies | ||
191 | * on other shared libs. Loading a "libfoo.so" could not solve the | ||
192 | * dependencies problem. | ||
193 | * | ||
194 | * You can, however, give a library name ending in ".so" | ||
195 | * (or whatever is used on your platform), and the library | ||
196 | * will be loaded without resolving dependencies. USE WITH CARE :) | ||
197 | * @return @ref KLibrary is invalid (0) when the library couldn't be dlopened. in such | ||
198 | * a case you can retrieve the error message by calling KLibLoader::lastErrorMessage() | ||
199 | * | ||
200 | * @see #factory | ||
201 | */ | ||
202 | virtual KLibrary* library( const char* libname ); | ||
203 | |||
204 | /** | ||
205 | * Loads and initializes a library. Loading a library multiple times is | ||
206 | * handled gracefully. The library is loaded such that the symbols are | ||
207 | * globally accessible so libraries with dependencies can be loaded | ||
208 | * sequentially. | ||
209 | * | ||
210 | * @param name This is the library name without extension. Usually that is something like | ||
211 | * "libkspread". The function will then search for a file named | ||
212 | * "libkspread.la" in the KDE library paths. | ||
213 | * The *.la files are created by libtool and contain | ||
214 | * important information especially about the libraries dependencies | ||
215 | * on other shared libs. Loading a "libfoo.so" could not solve the | ||
216 | * dependencies problem. | ||
217 | * | ||
218 | * You can, however, give a library name ending in ".so" | ||
219 | * (or whatever is used on your platform), and the library | ||
220 | * will be loaded without resolving dependencies. USE WITH CARE :) | ||
221 | * @return KLibrariy is invalid (0) when the library couldn't be dlopened. in such | ||
222 | * a case you can retrieve the error message by calling KLibLoader::lastErrorMessage() | ||
223 | * | ||
224 | * @see #factory | ||
225 | */ | ||
226 | KLibrary* globalLibrary( const char *name ); | ||
227 | |||
228 | /* | ||
229 | * Returns an error message that can be useful to debug the problem. | ||
230 | * Returns QString::null if the last call to @ref #library() was successful. | ||
231 | * You can call this function more than once. The error message is only | ||
232 | * reset by a new call to library(). | ||
233 | * @return the last error message, or QString::null if there was no error | ||
234 | */ | ||
235 | QString lastErrorMessage() const; | ||
236 | |||
237 | /** | ||
238 | * Unloads the library with the given name. | ||
239 | * @param libname This is the library name without extension. Usually that is something like | ||
240 | * "libkspread". The function will then search for a file named | ||
241 | * "libkspread.la" in the KDE library paths. | ||
242 | * The *.la files are created by libtool and contain | ||
243 | * important information especially about the libraries dependencies | ||
244 | * on other shared libs. Loading a "libfoo.so" could not solve the | ||
245 | * dependencies problem. | ||
246 | * | ||
247 | * You can, however, give a library name ending in ".so" | ||
248 | * (or whatever is used on your platform), and the library | ||
249 | * will be loaded without resolving dependencies. USE WITH CARE :) | ||
250 | */ | ||
251 | virtual void unloadLibrary( const char *libname ); | ||
252 | |||
253 | /** | ||
254 | * Returns a pointer to the factory. Use this function to get an instance | ||
255 | * of KLibLoader. | ||
256 | * @return a pointer to the loader. If no loader exists until now | ||
257 | * then one is created. | ||
258 | */ | ||
259 | static KLibLoader* self(); | ||
260 | |||
261 | /** | ||
262 | * @internal | ||
263 | * Internal Method, called by the KApplication destructor. | ||
264 | * Do not call it. | ||
265 | * This is what makes it possible to rely on ~KLibFactory | ||
266 | * being called in all cases, whether the library is unloaded | ||
267 | * while the application is running or when exiting. | ||
268 | */ | ||
269 | static void cleanUp(); | ||
270 | |||
271 | /** | ||
272 | * Helper method which looks for a library in the standard paths | ||
273 | * ("module" and "lib" resources). | ||
274 | * Made public for code that doesn't use KLibLoader itself, but still | ||
275 | * wants to open modules. | ||
276 | * @param name of the library. If it is not a path, the function searches in | ||
277 | * the "module" and "lib" resources. If there is no extension, | ||
278 | * ".la" will be appended. | ||
279 | * @param instance a KInstance used to get the standard paths | ||
280 | */ | ||
281 | static QString findLibrary( const char * name/*US , const KInstance * instance = KGlobal::instance()*/ ); | ||
282 | |||
283 | protected: | ||
284 | KLibLoader( QObject* parent = 0, const char* name = 0 ); | ||
285 | |||
286 | private slots: | ||
287 | void slotLibraryDestroyed(); | ||
288 | private: | ||
289 | void close_pending( KLibWrapPrivate * ); | ||
290 | QAsciiDict<KLibWrapPrivate> m_libs; | ||
291 | |||
292 | static KLibLoader* s_self; | ||
293 | |||
294 | protected: | ||
295 | virtual void virtual_hook( int id, void* data ); | ||
296 | private: | ||
297 | KLibLoaderPrivate *d; | ||
298 | }; | ||
299 | |||
300 | /** | ||
301 | * If you develop a library that is to be loaded dynamically at runtime, then | ||
302 | * you should return a pointer to your factory. The K_EXPORT_COMPONENT_FACTORY | ||
303 | * macro is provided for this purpose: | ||
304 | * <pre> | ||
305 | * K_EXPORT_COMPONENT_FACTORY( libkspread, KSpreadFactory ) | ||
306 | * </pre> | ||
307 | * | ||
308 | * The first macro argument is the name of your library, the second specifies the name | ||
309 | * of your factory. | ||
310 | * | ||
311 | * In the constructor of your factory you should create an instance of @ref KInstance | ||
312 | * like this: | ||
313 | * <pre> | ||
314 | * s_global = new KInstance( "kspread" ); | ||
315 | * </pre> | ||
316 | * This @ref KInstance is comparable to @ref KGlobal used by normal applications. | ||
317 | * It allows you to find resource files (images, XML, sound etc.) belonging | ||
318 | * to the library. | ||
319 | * | ||
320 | * If you want to load a library, use @ref KLibLoader. You can query @ref KLibLoader | ||
321 | * directly for a pointer to the libraries factory by using the @ref KLibLoader::factory() | ||
322 | * function. | ||
323 | * | ||
324 | * The KLibFactory is used to create the components, the library has to offer. | ||
325 | * The factory of KSpread for example will create instances of KSpreadDoc, | ||
326 | * while the Konqueror factory will create KonqView widgets. | ||
327 | * All objects created by the factory must be derived from @ref QObject, since @ref QObject | ||
328 | * offers type safe casting. | ||
329 | * | ||
330 | * KLibFactory is an abstract class. Reimplement the @ref | ||
331 | * createObject() method to give it functionality. | ||
332 | * | ||
333 | * @author Torben Weis <weis@kde.org> | ||
334 | */ | ||
335 | class KLibFactory : public QObject | ||
336 | { | ||
337 | Q_OBJECT | ||
338 | public: | ||
339 | /** | ||
340 | * Create a new factory. | ||
341 | * @param parent the parent of the QObject, 0 for no parent | ||
342 | * @param name the name of the QObject, 0 for no name | ||
343 | */ | ||
344 | KLibFactory( QObject* parent = 0, const char* name = 0 ); | ||
345 | virtual ~KLibFactory(); | ||
346 | |||
347 | /** | ||
348 | * Creates a new object. The returned object has to be derived from | ||
349 | * the requested classname. | ||
350 | * | ||
351 | * It is valid behavior to create different kinds of objects | ||
352 | * depending on the requested @p classname. For example a koffice | ||
353 | * library may usually return a pointer to KoDocument. But | ||
354 | * if asked for a "QWidget", it could create a wrapper widget, | ||
355 | * that encapsulates the Koffice specific features. | ||
356 | * | ||
357 | * create() automatically emits a signal @ref objectCreated to tell | ||
358 | * the library about its newly created object. This is very | ||
359 | * important for reference counting, and allows unloading the | ||
360 | * library automatically once all its objects have been destroyed. | ||
361 | * | ||
362 | * @param parent the parent of the QObject, 0 for no parent | ||
363 | * @param name the name of the QObject, 0 for no name | ||
364 | * @param classname the name of the class | ||
365 | * @param args a list of arguments | ||
366 | */ | ||
367 | |||
368 | QObject* create( QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList() ); | ||
369 | |||
370 | signals: | ||
371 | /** | ||
372 | * Emitted in #create | ||
373 | * @param obj the new object | ||
374 | */ | ||
375 | void objectCreated( QObject *obj ); | ||
376 | |||
377 | |||
378 | protected: | ||
379 | |||
380 | /** | ||
381 | * Creates a new object. The returned object has to be derived from | ||
382 | * the requested classname. | ||
383 | * | ||
384 | * It is valid behavior to create different kinds of objects | ||
385 | * depending on the requested @p classname. For example a koffice | ||
386 | * library may usually return a pointer to KoDocument. But | ||
387 | * if asked for a "QWidget", it could create a wrapper widget, | ||
388 | * that encapsulates the Koffice specific features. | ||
389 | * | ||
390 | * This function is called by #create() | ||
391 | * @param parent the parent of the QObject, 0 for no parent | ||
392 | * @param name the name of the QObject, 0 for no name | ||
393 | * @param classname the name of the class | ||
394 | * @param args a list of arguments | ||
395 | */ | ||
396 | virtual QObject* createObject( QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList() ) = 0; | ||
397 | |||
398 | |||
399 | protected: | ||
400 | virtual void virtual_hook( int id, void* data ); | ||
401 | private: | ||
402 | KLibFactoryPrivate *d; | ||
403 | }; | ||
404 | |||
405 | #endif | ||