• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • util
kpluginloader.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
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., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
17*/
18
19#include "kpluginloader.h"
20
21#include "kaboutdata.h"
22#include <kcomponentdata.h>
23#include <kstandarddirs.h>
24#include <klocale.h>
25#include "kpluginfactory.h"
26#include <kservice.h>
27#include "klibrary.h"
28#include <kdebug.h>
29
30#include <QtCore/QLibrary>
31#include <QtCore/QDir>
32#include <QtCore/QFileInfo>
33
34extern int kLibraryDebugArea();
35
36class KPluginLoaderPrivate
37{
38 Q_DECLARE_PUBLIC(KPluginLoader)
39protected:
40 KPluginLoaderPrivate(const QString &libname)
41 : name(libname), pluginVersion(~0U), verificationData(0), lib(0)
42 {}
43 ~KPluginLoaderPrivate()
44 {
45 delete lib;
46 }
47
48 KPluginLoader *q_ptr;
49 const QString name;
50 quint32 pluginVersion;
51 KDEPluginVerificationData *verificationData;
52 QString errorString;
53
54 KLibrary *lib;
55};
56
57inline QString makeLibName( const QString &libname )
58{
59#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
60 if (!libname.endsWith(QLatin1String(".dll")))
61 return libname + QLatin1String(".dll");
62 return libname;
63#else
64 int pos = libname.lastIndexOf(QLatin1Char('/'));
65 if (pos < 0)
66 pos = 0;
67 if (libname.indexOf(QLatin1Char('.'), pos) < 0) {
68 const char* const extList[] = { ".so", ".dylib", ".bundle", ".sl" };
69 for (uint i = 0; i < sizeof(extList) / sizeof(*extList); ++i) {
70 const QString lib = libname + QString::fromLatin1(extList[i]);
71 if (QLibrary::isLibrary(lib))
72 return lib;
73 }
74 }
75 return libname;
76#endif
77}
78
79#ifdef Q_OS_WIN
80extern QString fixLibPrefix(const QString& libname);
81#endif
82
83QString findLibraryInternal(const QString &name, const KComponentData &cData)
84{
85 // Convert name to a valid platform libname
86 QString libname = makeLibName(name);
87 QFileInfo fileinfo(name);
88 bool hasPrefix = fileinfo.fileName().startsWith(QLatin1String("lib"));
89 bool kdeinit = fileinfo.fileName().startsWith(QLatin1String("libkdeinit4_"));
90
91 if (hasPrefix && !kdeinit)
92 kDebug(kLibraryDebugArea()) << "plugins should not have a 'lib' prefix:" << libname;
93#ifdef Q_CC_MSVC
94 // first remove the 'lib' prefix in front of windows plugins
95 libname = fixLibPrefix(libname);
96#endif
97
98 // If it is a absolute path just return it
99 if (!QDir::isRelativePath(libname))
100 return libname;
101
102 // Start looking
103 QString libfile;
104
105 // Check for kde modules/plugins?
106 libfile = cData.dirs()->findResource("module", libname);
107 if (!libfile.isEmpty())
108 return libfile;
109
110 // Now look where they don't belong but sometimes are
111#ifndef Q_CC_MSVC
112 if (!hasPrefix)
113 libname = fileinfo.path() + QLatin1String("/lib") + fileinfo.fileName();
114#endif
115
116 libfile = cData.dirs()->findResource("lib", libname);
117 if (!libfile.isEmpty()) {
118 if (!kdeinit) {
119 kDebug(kLibraryDebugArea()) << "library" << libname << "not found under 'module' but under 'lib'";
120 }
121 return libfile;
122 }
123
124 // Nothing found
125 return QString();
126}
127
128bool KPluginLoader::isLoaded() const
129{
130 return QPluginLoader::isLoaded() || d_ptr->lib;
131}
132
133KPluginLoader::KPluginLoader(const QString &plugin, const KComponentData &componentdata, QObject *parent)
134 : QPluginLoader(findLibraryInternal(plugin, componentdata), parent), d_ptr(new KPluginLoaderPrivate(plugin))
135{
136 d_ptr->q_ptr = this;
137 Q_D(KPluginLoader);
138
139 // No lib, no fun.
140 if (fileName().isEmpty()) {
141 d->errorString = i18n(
142 "Could not find plugin '%1' for application '%2'",
143 plugin,
144 componentdata.aboutData()->appName());
145 return;
146 }
147}
148
149
150KPluginLoader::KPluginLoader(const KService &service, const KComponentData &componentdata, QObject *parent)
151: QPluginLoader(findLibraryInternal(service.library(), componentdata), parent), d_ptr(new KPluginLoaderPrivate(service.library()))
152{
153 d_ptr->q_ptr = this;
154 Q_D(KPluginLoader);
155
156 // It's probably to late to check this because service.library() is used
157 // above.
158 if (!service.isValid()) {
159 d->errorString = i18n("The provided service is not valid");
160 return;
161 }
162
163 // service.library() is used to find the lib. So first check if it is empty.
164 if (service.library().isEmpty()) {
165 d->errorString = i18n("The service '%1' provides no library or the Library key is missing", service.entryPath());
166 return;
167 }
168
169 // No lib, no fun. service.library() was set but we were still unable to
170 // find the lib.
171 if (fileName().isEmpty()) {
172 d->errorString = i18n(
173 "Could not find plugin '%1' for application '%2'",
174 service.name(),
175 componentdata.aboutData()->appName());
176 return;
177 }
178}
179
180KPluginLoader::~KPluginLoader()
181{
182 delete d_ptr;
183}
184
185KPluginFactory *KPluginLoader::factory()
186{
187 Q_D(KPluginLoader);
188
189 if (!load())
190 return 0;
191
192#ifndef KDE_NO_DEPRECATED
193 if (d->lib) {
194 // Calling a deprecated method, but this is the only way to
195 // support both new and old-style factories for now.
196 // KDE5: remove the whole if().
197 return d->lib->factory(d->name.toUtf8());
198 }
199#endif
200
201 QObject *obj = instance();
202
203 if (!obj)
204 return 0;
205
206 KPluginFactory *factory = qobject_cast<KPluginFactory *>(obj);
207
208 if (factory == 0) {
209 kDebug(kLibraryDebugArea()) << "Expected a KPluginFactory, got a" << obj->metaObject()->className();
210 delete obj;
211 d->errorString = i18n("The library %1 does not offer a KDE 4 compatible factory." , d->name);
212 }
213
214 return factory;
215}
216
217bool KPluginLoader::load()
218{
219 Q_D(KPluginLoader);
220
221 if (isLoaded())
222 return true;
223
224 if (!QPluginLoader::load()) {
225 d->lib = new KLibrary(d->name);
226 if (d->lib->load())
227 return true;
228
229 return false;
230 }
231
232 Q_ASSERT(!fileName().isEmpty());
233 QLibrary lib(fileName());
234 Q_ASSERT(lib.isLoaded()); // already loaded by QPluginLoader::load()
235
236 d->verificationData = (KDEPluginVerificationData *) lib.resolve("kde_plugin_verification_data");
237 if (d->verificationData) {
238 if (d->verificationData->dataVersion < KDEPluginVerificationData::PluginVerificationDataVersion
239 || ((d->verificationData->KDEVersion & 0xFFFF00) > (KDE_VERSION & 0xFFFF00)) // newer minor version
240 || (KDE_VERSION_MAJOR << 16 != (d->verificationData->KDEVersion & 0xFF0000))) // different major version
241 {
242 d->errorString = i18n("The plugin '%1' uses an incompatible KDE library (%2).", d->name, QString::fromLatin1(d->verificationData->KDEVersionString));
243 unload();
244 return false;
245 }
246 } else {
247 kDebug(kLibraryDebugArea()) << "The plugin" << d->name << "doesn't contain a kde_plugin_verification_data structure";
248 }
249
250 quint32 *version = (quint32 *) lib.resolve("kde_plugin_version");
251 if (version)
252 d->pluginVersion = *version;
253 else
254 d->pluginVersion = ~0U;
255
256 return true;
257}
258
259QString KPluginLoader::errorString() const
260{
261 Q_D(const KPluginLoader);
262
263 if (!d->errorString.isEmpty())
264 return d->errorString;
265
266 return QPluginLoader::errorString();
267}
268
269quint32 KPluginLoader::pluginVersion() const
270{
271 Q_D(const KPluginLoader);
272 const_cast<KPluginLoader*>(this)->load();
273 return d->pluginVersion;
274}
275
276QString KPluginLoader::pluginName() const
277{
278 Q_D(const KPluginLoader);
279 const_cast<KPluginLoader*>(this)->load();
280 return d->name;
281}
282
283#include "kpluginloader.moc"
KAboutData::appName
QString appName() const
Returns the application's internal name.
Definition: kaboutdata.cpp:678
KComponentData
Per component data.
Definition: kcomponentdata.h:47
KComponentData::dirs
KStandardDirs * dirs() const
Returns the application standard dirs object.
Definition: kcomponentdata.cpp:193
KComponentData::aboutData
const KAboutData * aboutData() const
Returns the about data of this component.
Definition: kcomponentdata.cpp:215
KLibrary
Thin wrapper around QLibrary; you should rarely use this directly, see KPluginLoader for higher-level...
Definition: klibrary.h:39
KPluginFactory
If you develop a library that is to be loaded dynamically at runtime, then you should return a pointe...
Definition: kpluginfactory.h:233
KPluginLoader
This class can be used to dynamically load a plugin library at runtime.
Definition: kpluginloader.h:80
KPluginLoader::isLoaded
bool isLoaded() const
Definition: kpluginloader.cpp:128
KPluginLoader::errorString
QString errorString() const
Queries the last error.
Definition: kpluginloader.cpp:259
KPluginLoader::load
bool load()
Performs the loading of the plugin.
Definition: kpluginloader.cpp:217
KPluginLoader::factory
KPluginFactory * factory()
Used to obtain the factory object of the plugin.
Definition: kpluginloader.cpp:185
KPluginLoader::~KPluginLoader
~KPluginLoader()
Destroys the plugin loader.
Definition: kpluginloader.cpp:180
KPluginLoader::fileName
QString fileName
Definition: kpluginloader.h:82
KPluginLoader::pluginName
QString pluginName
Definition: kpluginloader.h:83
KPluginLoader::KPluginLoader
KPluginLoader(const QString &plugin, const KComponentData &componentdata=KGlobal::mainComponent(), QObject *parent=0)
Used this constructor to load a plugin with a given library name.
Definition: kpluginloader.cpp:133
KPluginLoader::pluginVersion
quint32 pluginVersion() const
Queries the plugin version.
Definition: kpluginloader.cpp:269
KService
Represent a service, like an application or plugin bound to one or several mimetypes (or servicetypes...
Definition: kservice.h:59
KService::library
QString library() const
Returns the name of the service's library.
Definition: kservice.cpp:857
KStandardDirs::findResource
QString findResource(const char *type, const QString &filename) const
Tries to find a resource in the following order:
Definition: kstandarddirs.cpp:458
KSycocaEntry::isValid
bool isValid() const
Definition: ksycocaentry.cpp:151
KSycocaEntry::name
QString name() const
Definition: ksycocaentry.cpp:157
KSycocaEntry::entryPath
QString entryPath() const
Definition: ksycocaentry.cpp:104
QLibrary
QObject
QPluginLoader
QString
quint32
kDebug
#define kDebug
Definition: kdebug.h:316
kaboutdata.h
kcomponentdata.h
kdebug.h
kLibraryDebugArea
int kLibraryDebugArea()
Definition: klibrary.cpp:33
klibrary.h
klocale.h
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
kpluginfactory.h
findLibraryInternal
QString findLibraryInternal(const QString &name, const KComponentData &cData)
Definition: kpluginloader.cpp:83
kLibraryDebugArea
int kLibraryDebugArea()
Definition: klibrary.cpp:33
fixLibPrefix
QString fixLibPrefix(const QString &libname)
Definition: klibloader.cpp:66
makeLibName
QString makeLibName(const QString &libname)
Definition: kpluginloader.cpp:57
kpluginloader.h
kservice.h
kstandarddirs.h
KDEPluginVerificationData
Definition: kexportplugin.h:33
KDEPluginVerificationData::PluginVerificationDataVersion
@ PluginVerificationDataVersion
Definition: kexportplugin.h:34
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal