KDECore
klibrary.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999 Torben Weis <weis@kde.org> 00003 Copyright (C) 2000 Michael Matz <matz@kde.org> 00004 Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 #include "klibrary.h" 00021 00022 #include <QtCore/QDir> 00023 #include <QtCore/QPointer> 00024 00025 #include <kcomponentdata.h> 00026 #include <kstandarddirs.h> 00027 #include <kpluginfactory.h> 00028 #include <kdebug.h> 00029 00030 extern QString makeLibName( const QString &libname ); 00031 extern QString findLibraryInternal(const QString &name, const KComponentData &cData); 00032 00033 int kLibraryDebugArea() { 00034 static int s_area = KDebug::registerArea("kdecore (KLibrary)"); 00035 return s_area; 00036 } 00037 00038 //static 00039 QString findLibrary(const QString &name, const KComponentData &cData) 00040 { 00041 QString libname = findLibraryInternal(name, cData); 00042 #ifdef Q_OS_WIN 00043 // we don't have 'lib' prefix on windows -> remove it and try again 00044 if( libname.isEmpty() ) 00045 { 00046 libname = name; 00047 QString file, path; 00048 00049 int pos = libname.lastIndexOf( QLatin1Char('/') ); 00050 if ( pos >= 0 ) 00051 { 00052 file = libname.mid( pos + 1 ); 00053 path = libname.left( pos ); 00054 libname = path + QLatin1Char('/') + file.mid( 3 ); 00055 } 00056 else 00057 { 00058 file = libname; 00059 libname = file.mid( 3 ); 00060 } 00061 if( !file.startsWith( QLatin1String("lib") ) ) 00062 return file; 00063 00064 libname = findLibraryInternal(libname, cData); 00065 if( libname.isEmpty() ) 00066 libname = name; 00067 } 00068 #endif 00069 return libname; 00070 } 00071 00072 00073 KLibrary::KLibrary(QObject *parent) 00074 : QLibrary(parent), d_ptr(0) 00075 { 00076 } 00077 00078 KLibrary::KLibrary(const QString &name, const KComponentData &cData, QObject *parent) 00079 : QLibrary(findLibrary(name, cData), parent), d_ptr(0) 00080 { 00081 } 00082 00083 KLibrary::KLibrary(const QString &name, int verNum, const KComponentData &cData, QObject *parent) 00084 : QLibrary(findLibrary(name, cData), verNum, parent), d_ptr(0) 00085 { 00086 } 00087 00088 KLibrary::~KLibrary() 00089 { 00090 } 00091 00092 typedef QHash<QString, QPointer<KPluginFactory> > FactoryHash; 00093 00094 K_GLOBAL_STATIC(FactoryHash, s_createdKde3Factories) 00095 00096 static KPluginFactory* kde3Factory(KLibrary *lib, const QByteArray &factoryname) 00097 { 00098 QByteArray symname = "init_"; 00099 if(!factoryname.isEmpty()) { 00100 symname += factoryname; 00101 } else { 00102 symname += QFileInfo(lib->fileName()).fileName().split(QLatin1Char('.')).first().toLatin1(); 00103 } 00104 00105 const QString hashKey = lib->fileName() + QLatin1Char(':') + QString::fromLatin1(symname); 00106 KPluginFactory *factory = s_createdKde3Factories->value(hashKey); 00107 if (factory) { 00108 return factory; 00109 } 00110 00111 typedef KPluginFactory* (*t_func)(); 00112 t_func func = reinterpret_cast<t_func>(lib->resolveFunction( symname )); 00113 if ( !func ) 00114 { 00115 #ifdef Q_OS_WIN 00116 // a backup for cases when developer has set lib prefix for a plugin name (she should not...) 00117 if (!factoryname.startsWith("lib")) 00118 return kde3Factory(lib, QByteArray("lib")+symname.mid(5 /*"init_"*/)); 00119 #endif 00120 kDebug(kLibraryDebugArea()) << "The library" << lib->fileName() << "does not offer an" 00121 << symname << "function."; 00122 return 0; 00123 } 00124 00125 factory = func(); 00126 00127 if( !factory ) 00128 { 00129 kDebug(kLibraryDebugArea()) << "The library" << lib->fileName() << "does not offer a KDE compatible factory."; 00130 return 0; 00131 } 00132 s_createdKde3Factories->insert(hashKey, factory); 00133 00134 return factory; 00135 } 00136 00137 static KPluginFactory *kde4Factory(KLibrary *lib) 00138 { 00139 const QByteArray symname("qt_plugin_instance"); 00140 00141 typedef QObject* (*t_func)(); 00142 t_func func = reinterpret_cast<t_func>(lib->resolveFunction(symname)); 00143 if ( !func ) 00144 { 00145 kDebug(kLibraryDebugArea()) << "The library" << lib->fileName() << "does not offer a qt_plugin_instance function."; 00146 return 0; 00147 } 00148 00149 QObject* instance = func(); 00150 KPluginFactory *factory = qobject_cast<KPluginFactory *>(instance); 00151 00152 if( !factory ) 00153 { 00154 if (instance) 00155 kDebug(kLibraryDebugArea()) << "Expected a KPluginFactory, got a" << instance->metaObject()->className(); 00156 kDebug(kLibraryDebugArea()) << "The library" << lib->fileName() << "does not offer a KDE 4 compatible factory."; 00157 return 0; 00158 } 00159 return factory; 00160 } 00161 00162 // deprecated 00163 KPluginFactory* KLibrary::factory(const char* factoryname) 00164 { 00165 if (fileName().isEmpty()) { 00166 return NULL; 00167 } 00168 00169 KPluginFactory *factory = kde4Factory(this); 00170 if (!factory) 00171 factory = kde3Factory(this, factoryname); 00172 00173 return factory; 00174 } 00175 00176 void *KLibrary::resolveSymbol( const char* symname ) 00177 { 00178 return resolve( symname ); 00179 } 00180 00181 KLibrary::void_function_ptr KLibrary::resolveFunction( const char* symname ) 00182 { 00183 void *psym = resolve( symname ); 00184 if (!psym) 00185 return 0; 00186 00187 // Cast the void* to non-pointer type first - it's not legal to 00188 // cast a pointer-to-object directly to a pointer-to-function. 00189 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t>(psym); 00190 void_function_ptr sym = reinterpret_cast<void_function_ptr>(tmp); 00191 00192 return sym; 00193 } 00194 00195 void KLibrary::setFileName(const QString &name, const KComponentData &data) 00196 { 00197 QLibrary::setFileName(findLibrary(name, data)); 00198 } 00199 00200 #include "klibrary.moc"
KDE 4.6 API Reference