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

source code of qtbase/src/corelib/plugin/qlibrary_p.h