summaryrefslogtreecommitdiffstats
path: root/kdecore/klibloader.h
diff options
context:
space:
mode:
Diffstat (limited to 'kdecore/klibloader.h')
-rw-r--r--kdecore/klibloader.h405
1 files changed, 405 insertions, 0 deletions
diff --git a/kdecore/klibloader.h b/kdecore/klibloader.h
new file mode 100644
index 000000000..1230f9944
--- /dev/null
+++ b/kdecore/klibloader.h
@@ -0,0 +1,405 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1999 Torben Weis <weis@kde.org>
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KLIBLOADER_H
+#define KLIBLOADER_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qasciidict.h>
+#include <qptrlist.h>
+#include <kglobal.h>
+
+#include <stdlib.h> // For backwards compatibility
+
+class KInstance;
+class QTimer;
+class KLibrary;
+class KLibFactory;
+class KLibFactoryPrivate;
+class KLibLoaderPrivate;
+class KLibraryPrivate;
+
+# define K_EXPORT_COMPONENT_FACTORY( libname, factory ) \
+ extern "C" { KDE_EXPORT void *init_##libname() { return new factory; } }
+
+/**
+ * @short Represents a dynamically loaded library.
+ *
+ * KLibrary allows you to look up symbols of the shared library.
+ * Use KLibLoader to create a new instance of KLibrary.
+ *
+ * @see KLibLoader
+ * @author Torben Weis <weis@kde.org>
+ */
+class KDECORE_EXPORT KLibrary : public QObject
+{
+ friend class KLibLoader;
+ friend class QAsciiDict<KLibrary>;
+
+ Q_OBJECT
+public:
+ /**
+ * Don't create KLibrary objects on your own. Instead use KLibLoader.
+ */
+ KLibrary( const QString& libname, const QString& filename, void * handle );
+
+ /**
+ * Returns the name of the library.
+ * @return The name of the library like "libkspread".
+ */
+ QString name() const;
+
+ /**
+ * Returns the file name of the library.
+ * @return The filename of the library, for example "/opt/kde2&/lib/libkspread.la"
+ */
+ QString fileName() const;
+
+ /**
+ * Returns the factory of the library.
+ * @return The factory of the library if there is any, otherwise 0
+ */
+ KLibFactory* factory();
+
+ /**
+ * Looks up a symbol from the library. This is a very low level
+ * function that you usually don't want to use. Usually you should
+ * check using hasSymbol() whether the symbol actually exists,
+ * otherwise a warning will be printed.
+ * @param name the name of the symbol to look up
+ * @return the address of the symbol, or 0 if it does not exist
+ * @see hasSymbol
+ */
+ void* symbol( const char* name ) const;
+
+ /**
+ * Looks up a symbol from the library. This is a very low level
+ * function that you usually don't want to use.
+ * Unlike symbol(), this method doesn't warn if the symbol doesn't exist,
+ * so if the symbol might or might not exist, better use hasSymbol() before symbol().
+ * @param name the name of the symbol to check
+ * @return true if the symbol exists
+ * @since 3.1
+ */
+ bool hasSymbol( const char* name ) const;
+
+ /**
+ * Unloads the library.
+ * This typically results in the deletion of this object. You should
+ * not reference its pointer after calling this function.
+ */
+ void unload() const;
+
+private slots:
+ void slotObjectCreated( QObject *obj );
+ void slotObjectDestroyed();
+ void slotTimeout();
+
+private:
+ /**
+ * @internal
+ * Don't destruct KLibrary objects yourself. Instead use unload() instead.
+ */
+ ~KLibrary();
+
+ QString m_libname;
+ QString m_filename;
+ KLibFactory* m_factory;
+ void * m_handle;
+ QPtrList<QObject> m_objs;
+ QTimer *m_timer;
+ KLibraryPrivate *d;
+};
+
+class KLibWrapPrivate;
+
+/**
+ * The KLibLoader allows you to load libraries dynamically at runtime.
+ * Dependent libraries are loaded automatically.
+ *
+ * KLibLoader follows the singleton pattern. You can not create multiple
+ * instances. Use self() to get a pointer to the loader.
+ *
+ * @see KLibrary
+ * @author Torben Weis <weis@kde.org>
+ */
+class KDECORE_EXPORT KLibLoader : public QObject
+{
+ friend class KLibrary;
+
+ 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
+ * @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 caution.
+ * @return the KLibFactory, or 0 if the library does not exist or it does
+ * not have a factory
+ * @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 caution.
+ * @return KLibrary 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 name 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 caution.
+ * @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() was successful.
+ * You can call this function more than once. The error message is only
+ * reset by a new call to library().
+ * @return the last error message, or QString::null if there was no error
+ */
+ QString lastErrorMessage() const;
+
+ /**
+ * Unloads the library with the given name.
+ * @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 caution.
+ */
+ virtual void unloadLibrary( const char *libname );
+
+ /**
+ * Returns a pointer to the factory. Use this function to get an instance
+ * of KLibLoader.
+ * @return a pointer to the loader. If no loader exists until now
+ * then one is created.
+ */
+ static KLibLoader* self();
+
+ /**
+ * @internal
+ * Internal Method, called by the KApplication destructor.
+ * Do not call it.
+ * 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.
+ * @param name of the library. If it is not a path, the function searches in
+ * the "module" and "lib" resources. If there is no extension,
+ * ".la" will be appended.
+ * @param instance a KInstance used to get the standard paths
+ */
+ 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<KLibWrapPrivate> m_libs;
+
+ static KLibLoader* s_self;
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ KLibLoaderPrivate *d;
+};
+
+/**
+ * If you develop a library that is to be loaded dynamically at runtime, then
+ * you should return a pointer to your factory. The K_EXPORT_COMPONENT_FACTORY
+ * macro is provided for this purpose:
+ * \code
+ * K_EXPORT_COMPONENT_FACTORY( libkspread, KSpreadFactory )
+ * \endcode
+ *
+ * The first macro argument is the name of your library, the second specifies the name
+ * of your factory.
+ *
+ * NOTE: you probably want to use KGenericFactory<PluginClassName>
+ * instead of writing your own factory.
+ *
+ * In the constructor of your factory you should create an instance of KInstance
+ * like this:
+ * \code
+ * s_global = new KInstance( "kspread" );
+ * \endcode
+ * This KInstance is comparable to KGlobal used by normal applications.
+ * It allows you to find resource files (images, XML, sound etc.) belonging
+ * to the library.
+ *
+ * If you want to load a library, use KLibLoader. You can query KLibLoader
+ * directly for a pointer to the libraries factory by using the 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 QObject, since QObject
+ * offers type safe casting.
+ *
+ * KLibFactory is an abstract class. Reimplement the
+ * createObject() method to give it functionality.
+ *
+ * @author Torben Weis <weis@kde.org>
+ */
+class KDECORE_EXPORT KLibFactory : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Create a new factory.
+ * @param parent the parent of the QObject, 0 for no parent
+ * @param name the name of the QObject, 0 for no name
+ */
+ 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 KoDocument. But
+ * if asked for a "QWidget", it could create a wrapper widget,
+ * that encapsulates the Koffice specific features.
+ *
+ * create() automatically emits a signal 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.
+ *
+ * @param parent the parent of the QObject, 0 for no parent
+ * @param name the name of the QObject, 0 for no name
+ * @param classname the name of the class
+ * @param args a list of arguments
+ */
+
+ QObject* create( QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList() );
+
+signals:
+ /**
+ * Emitted in #create
+ * @param obj the new object
+ */
+ 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 KoDocument. But
+ * if asked for a "QWidget", it could create a wrapper widget,
+ * that encapsulates the Koffice specific features.
+ *
+ * This function is called by #create()
+ * @param parent the parent of the QObject, 0 for no parent
+ * @param name the name of the QObject, 0 for no name
+ * @param className the name of the class
+ * @param args a list of arguments
+ */
+ virtual QObject* createObject( QObject* parent = 0, const char* name = 0,
+ const char* className = "QObject",
+ const QStringList &args = QStringList() ) = 0;
+
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ KLibFactoryPrivate *d;
+};
+
+#endif