1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
// Copyright (C) 2020 The Qt Company Ltd.
// Copyright (C) 2021 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLIBRARY_P_H
#define QLIBRARY_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of the QLibrary class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include "QtCore/qlibrary.h"
#include "QtCore/private/qplugin_p.h"
#include "QtCore/qloggingcategory.h"
#include "QtCore/qmutex.h"
#include "QtCore/qplugin.h"
#include "QtCore/qpointer.h"
#include "QtCore/qstringlist.h"
#ifdef Q_OS_WIN
# include "QtCore/qt_windows.h"
#endif
#include <memory>
QT_REQUIRE_CONFIG(library);
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(qt_lcDebugPlugins)
struct QLibraryScanResult
{
qsizetype pos;
qsizetype length;
#if defined(Q_OF_MACH_O)
bool isEncrypted = false;
#endif
};
class QLibraryStore;
class QLibraryPrivate
{
public:
#ifdef Q_OS_WIN
using Handle = HINSTANCE;
#else
using Handle = void *;
#endif
enum UnloadFlag { UnloadSys, NoUnloadSys };
struct Deleter {
// QLibraryPrivate::release() is not, yet, and cannot easily be made, noexcept:
void operator()(QLibraryPrivate *p) const { p->release(); }
};
using UniquePtr = std::unique_ptr<QLibraryPrivate, Deleter>;
const QString fileName;
const QString fullVersion;
bool load();
QtPluginInstanceFunction loadPlugin(); // loads and resolves instance
Q_AUTOTEST_EXPORT bool unload(UnloadFlag flag = UnloadSys);
void release();
QFunctionPointer resolve(const char *);
QLibrary::LoadHints loadHints() const
{ return QLibrary::LoadHints(loadHintsInt.loadRelaxed()); }
void setLoadHints(QLibrary::LoadHints lh);
QObject *pluginInstance();
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString(),
QLibrary::LoadHints loadHints = { });
static QStringList suffixes_sys(const QString &fullVersion);
static constexpr QStringView prefix_sys()
{
#ifdef Q_OS_WIN
return {};
#elif defined(Q_OS_CYGWIN)
return u"cyg";
#else
return u"lib";
#endif
}
QAtomicPointer<std::remove_pointer<QtPluginInstanceFunction>::type> instanceFactory;
QAtomicPointer<std::remove_pointer<Handle>::type> pHnd;
// the mutex protects the fields below
QMutex mutex;
QPointer<QObject> inst; // used by QFactoryLoader
QPluginParsedMetaData metaData;
QString errorString;
QString qualifiedFileName;
void updatePluginState();
bool isPlugin();
static QLibraryPrivate* get(QLibrary* lib)
{
return lib->d.data();
}
private:
explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints);
~QLibraryPrivate();
void mergeLoadHints(QLibrary::LoadHints loadHints);
bool load_sys();
bool unload_sys();
QFunctionPointer resolve_sys(const char *);
QAtomicInt loadHintsInt;
/// counts how many QLibrary or QPluginLoader are attached to us, plus 1 if it's loaded
QAtomicInt libraryRefCount;
/// counts how many times load() or loadPlugin() were called
QAtomicInt libraryUnloadCount;
enum { IsAPlugin, IsNotAPlugin, MightBeAPlugin } pluginState;
friend class QLibraryStore;
};
QT_END_NAMESPACE
#endif // QLIBRARY_P_H
|