Source: klibloader.h


Annotated List
Files
Globals
Hierarchy
Index
/* This file is part of the KDE libraries
   Copyright (C) 1999 Torben Weis 

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/
#ifndef KLIBLOADER_H
#define KLIBLOADER_H

#include 
#include 
#include 
#include 
#include 
#include 

#include  // For backwards compatibility

class KInstance;
class QTimer;
class KLibFactoryPrivate;
class KLibLoaderPrivate;
class KLibraryPrivate;

/**
 * If you develop a library that is to be loaded dynamically at runtime, then
 * you should provide a function that returns a pointer to your factory like this:
 * 
 * extern "C"
 * {
 *   void* init_libkspread()
 *   {
 *     return new KSpreadFactory;
 *   }
 * };
 * 
* You should especially see that the function must follow the naming pattern * "init_libname". * * In the constructor of your factory you should create an instance of @ref KInstance * like this: *
 *     s_global = new KInstance( "kspread" );
 * 
* This @ref KInstance is compareable to @ref KGlobal used by normal applications. * It allows you to find ressource files (images, XML, sound etc.) belonging * to the library. * * If you want to load a library, use @ref KLibLoader. You can query @ref KLibLoader * directly for a pointer to the libraries factory by using the @ref KLibLoader::factory() * function. * * The KLibFactory is used to create the components, the library has to offer. * The factory of KSpread for example will create instances of KSpreadDoc, * while the Konqueror factory will create KonqView widgets. * All objects created by the factory must be derived from @ref QObject, since @ref QObject * offers type safe casting. * * KLibFactory is an abstract class. Reimplement the @ref * createObject() method to give it functionality. * * @author Torben Weis */ class KLibFactory : public QObject { Q_OBJECT public: /** * Create a new factory. */ KLibFactory( QObject* parent = 0, const char* name = 0 ); virtual ~KLibFactory(); /** * Creates a new object. The returned object has to be derived from * the requested classname. * * It is valid behavior to create different kinds of objects * depending on the requested @p classname. For example a koffice * library may usually return a pointer to @ref KoDocument. But * if asked for a "QWidget", it could create a wrapper widget, * that encapsulates the Koffice specific features. * * Never reimplement this function. Instead, reimplement @ref * createObject(). * * create() automatically emits a signal @ref objectCreated to tell * the library about its newly created object. This is very * important for reference counting, and allows unloading the * library automatically once all its objects have been destroyed. * * This function is virtual for compatibility reasons only. */ virtual QObject* create( QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList() ); signals: /** * Emitted in @ref create */ void objectCreated( QObject *obj ); protected: /** * Creates a new object. The returned object has to be derived from * the requested classname. * * It is valid behavior to create different kinds of objects * depending on the requested @p classname. For example a koffice * library may usually return a pointer to @ref KoDocument. But * if asked for a "QWidget", it could create a wrapper widget, * that encapsulates the Koffice specific features. * * This function is called by @ref create() */ virtual QObject* createObject( QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList() ); private: KLibFactoryPrivate *d; }; /** * @short Represents a dynamically loaded library. * * KLibrary allows you to look up symbols of the shared library. * * @author Torben Weis */ class KLibrary : public QObject { Q_OBJECT public: /** * @internal * Don't create KLibrary objects on your own. Instead use @ref KLibLoader. */ KLibrary( const QString& libname, const QString& filename, void * handle ); /** * @internal * Don't destruct KLibrary objects yourself. Instead use @ref KLibLoader::unloadLibrary. */ ~KLibrary(); /** * @return The name of the library like "libkspread". */ QString name() const; /** * @return The filename of the library, for example "/opt/kde2&/lib/libkspread.la" */ QString fileName() const; /** * @return The factory of the library if there is any. */ KLibFactory* factory(); /** * Looks up a symbol from the library. This is a very low level * function that you usually dont want to use. */ void* symbol( const char* name ); private slots: void slotObjectCreated( QObject *obj ); void slotObjectDestroyed(); void slotTimeout(); private: QString m_libname; QString m_filename; KLibFactory* m_factory; void * m_handle; QList m_objs; QTimer *m_timer; KLibraryPrivate *d; }; class KLibWrapPrivate; /** * The KLibLoader allows you to load libraries dynamically at runtime. * Dependend libraries are loaded automatically. * * KLibLoader follows the singleton pattern. You can not create multiple * instances. Use @ref #self() to get a pointer to the loader. * * @author Torben Weis */ class KLibLoader : public QObject { Q_OBJECT public: /** * You should NEVER destruct an instance of KLibLoader * until you know what you are doing. This will release * the loaded libraries. */ ~KLibLoader(); /** * Loads and initializes a library. Loading a library multiple times is * handled gracefully. * * This is a convenience function that returns the factory immediately * * @see #library */ KLibFactory* factory( const char* libname ); /** * Loads and initializes a library. Loading a library multiple times is * handled gracefully. * * @param libname This is the library name without extension. Usually that is something like * "libkspread". The function will then search for a file named * "libkspread.la" in the KDE library paths. * The *.la files are created by libtool and contain * important information especially about the libraries dependencies * on other shared libs. Loading a "libfoo.so" could not solve the * dependencies problem. * * You can, however, give a library name ending in ".so" * (or whatever is used on your platform), and the library * will be loaded without resolving dependencies. USE WITH CARE :) * @return KLibrariy is invalid (0) when the library couldn't be dlopened. in such * a case you can retrieve the error message by calling KLibLoader::lastErrorMessage() * * @see #factory */ virtual KLibrary* library( const char* libname ); /** * Loads and initializes a library. Loading a library multiple times is * handled gracefully. The library is loaded such that the symbols are * globally accessible so libraries with dependencies can be loaded * sequentially. * * @param libname This is the library name without extension. Usually that is something like * "libkspread". The function will then search for a file named * "libkspread.la" in the KDE library paths. * The *.la files are created by libtool and contain * important information especially about the libraries dependencies * on other shared libs. Loading a "libfoo.so" could not solve the * dependencies problem. * * You can, however, give a library name ending in ".so" * (or whatever is used on your platform), and the library * will be loaded without resolving dependencies. USE WITH CARE :) * @return KLibrariy is invalid (0) when the library couldn't be dlopened. in such * a case you can retrieve the error message by calling KLibLoader::lastErrorMessage() * * @see #factory */ KLibrary* globalLibrary( const char *name ); /* * returns an error message that can be useful to debug the problem * returns QString::null if the last call to ::library(const char*) was successful * you can call this function more than once. The error message is only * reset by a new call to library(). */ QString lastErrorMessage() const; virtual void unloadLibrary( const char *libname ); /** * @return a pointer to the loader. If no loader exists until now * then one is created. */ static KLibLoader* self(); /** * @internal method, called by the KApplication destructor * This is what makes it possible to rely on ~KLibFactory * being called in all cases, whether the library is unloaded * while the application is running or when exiting. */ static void cleanUp(); /** * Helper method which looks for a library in the standard paths * ("module" and "lib" resources) * Made public for code that doesn't use KLibLoader itself, but still * wants to open modules. */ static QString findLibrary( const char * name, const KInstance * instance = KGlobal::instance() ); protected: KLibLoader( QObject* parent = 0, const char* name = 0 ); private slots: void slotLibraryDestroyed(); private: void close_pending( KLibWrapPrivate * ); QAsciiDict m_libs; static KLibLoader* s_self; KLibLoaderPrivate *d; }; #endif

Generated by: dfaure on kde.faure.org on Thu Jan 17 22:15:01 2002, using kdoc 2.0a53.