Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsymbolsresolveutils_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:execute-external-code
4
5#ifndef Q_SYMBOLSRESOLVEUTILS
6#define Q_SYMBOLSRESOLVEUTILS
7
8#include <QtCore/qlibrary.h>
9#include <QtMultimedia/qtmultimediaexports.h>
10#include <tuple>
11#include <memory>
12#include <string_view>
13
14//
15// W A R N I N G
16// -------------
17//
18// This file is not part of the Qt API. It exists purely as an
19// implementation detail. This header file may change from version to
20// version without notice, or even be removed.
21//
22// We mean it.
23//
24
26
27constexpr bool areVersionsEqual(const char lhs[], const char rhs[])
28{
29 return std::string_view(lhs) == std::string_view(rhs);
30}
31
32constexpr bool areVersionsEqual(const char lhs[], int rhsInt)
33{
34 int lhsInt = 0;
35 for (int i = 0; lhs[i]; ++i) {
36 if (lhs[i] < '0' || lhs[i] > '9')
37 return false;
38
39 lhsInt *= 10;
40 lhsInt += lhs[i] - '0';
41 }
42
43 return lhsInt == rhsInt;
44}
45
46
47template <typename T>
49{
50 template <typename... Arg>
51 T operator()(Arg &&...) { return val; }
52 T val;
53};
54
55template <>
56struct DefaultReturn<void>
57{
58 template <typename... Arg>
59 void operator()(Arg &&...) { }
60};
61
62template <typename...>
63struct FuncInfo;
64
65template <typename R, typename... A>
66struct FuncInfo<R(A...)>
67{
68 using Return = R;
69 using Args = std::tuple<A...>;
70};
71
72class Q_MULTIMEDIA_EXPORT SymbolsResolver
73{
74public:
75 using LibraryLoader = std::unique_ptr<QLibrary> (*)();
76 static bool isLazyLoadEnabled();
77 bool isLoaded() const { return m_library != nullptr; }
78
79 ~SymbolsResolver();
80protected:
81 SymbolsResolver(const char *libLoggingName, LibraryLoader loader);
82
83 SymbolsResolver(const char *libName, const char *version = "",
84 const char *libLoggingName = nullptr);
85
86 QFunctionPointer initOptionalFunction(const char *name);
87 QFunctionPointer initFunction(const char *name);
88
89 struct SymbolsMarker {};
90 void checkLibrariesLoaded(SymbolsMarker *begin, SymbolsMarker *end);
91
92private:
93 const char *m_libLoggingName;
94 std::unique_ptr<QLibrary> m_library;
95};
96
97
98QT_END_NAMESPACE
99
100// clang-format off
101
102#define CHECK_VERSIONS(Name, NeededSoversion, DetectedVersion)
103 static_assert(areVersionsEqual(NeededSoversion, DetectedVersion),
104 "Configuartion error: misleading " Name " versions!")
105
106#define BEGIN_INIT_FUNCS(...)
107 QT_USE_NAMESPACE
108 namespace {
109 class SymbolsResolverImpl : public SymbolsResolver {
110 public:
111 SymbolsResolverImpl() : SymbolsResolver(__VA_ARGS__)
112 { checkLibrariesLoaded(&symbolsBegin, &symbolsEnd); }
113 static const SymbolsResolverImpl& instance()
114 { static const SymbolsResolverImpl instance; return instance; }
115 SymbolsMarker symbolsBegin;
116
117#define INIT_FUNC(F) QFunctionPointer F = initFunction(#F);
118#define INIT_OPT_FUNC(F) QFunctionPointer F = initOptionalFunction(#F);
119
120#define END_INIT_FUNCS()
121 SymbolsMarker symbolsEnd;
122 };
123 [[maybe_unused]] static const auto *instantResolver =
124 SymbolsResolver::isLazyLoadEnabled() ? &SymbolsResolverImpl::instance() : nullptr;
125 }
126
127
128#ifdef Q_EXPORT_STUB_SYMBOLS
129#define EXPORT_FUNC Q_MULTIMEDIA_EXPORT
130#else
131#define EXPORT_FUNC
132#endif
133
134#define DEFINE_FUNC_IMPL(F, Vars, TypesWithVars, ReturnFunc)
135 using F##_ReturnType = FuncInfo<decltype(F)>::Return;
136 extern "C" EXPORT_FUNC [[maybe_unused]] F##_ReturnType F(TypesWithVars(F)) {
137 using F##_Type = F##_ReturnType (*)(TypesWithVars(F));
138 const auto f = SymbolsResolverImpl::instance().F;
139 return f ? (reinterpret_cast<F##_Type>(f))(Vars()) : ReturnFunc();
140 }
141
142
143#define VAR(I) a##I
144#define VARS0()
145#define VARS1() VAR(0)
146#define VARS2() VARS1(), VAR(1)
147#define VARS3() VARS2(), VAR(2)
148#define VARS4() VARS3(), VAR(3)
149#define VARS5() VARS4(), VAR(4)
150#define VARS6() VARS5(), VAR(5)
151#define VARS7() VARS6(), VAR(6)
152#define VARS8() VARS7(), VAR(7)
153#define VARS9() VARS8(), VAR(8)
154#define VARS10() VARS9(), VAR(9)
155#define VARS11() VARS10(), VAR(10)
156
157#define TYPE_WITH_VAR(F, I) std::tuple_element_t<I, FuncInfo<decltype(F)>::Args> VAR(I)
158#define TYPES_WITH_VARS0(F)
159#define TYPES_WITH_VARS1(F) TYPE_WITH_VAR(F, 0)
160#define TYPES_WITH_VARS2(F) TYPES_WITH_VARS1(F), TYPE_WITH_VAR(F, 1)
161#define TYPES_WITH_VARS3(F) TYPES_WITH_VARS2(F), TYPE_WITH_VAR(F, 2)
162#define TYPES_WITH_VARS4(F) TYPES_WITH_VARS3(F), TYPE_WITH_VAR(F, 3)
163#define TYPES_WITH_VARS5(F) TYPES_WITH_VARS4(F), TYPE_WITH_VAR(F, 4)
164#define TYPES_WITH_VARS6(F) TYPES_WITH_VARS5(F), TYPE_WITH_VAR(F, 5)
165#define TYPES_WITH_VARS7(F) TYPES_WITH_VARS6(F), TYPE_WITH_VAR(F, 6)
166#define TYPES_WITH_VARS8(F) TYPES_WITH_VARS7(F), TYPE_WITH_VAR(F, 7)
167#define TYPES_WITH_VARS9(F) TYPES_WITH_VARS8(F), TYPE_WITH_VAR(F, 8)
168#define TYPES_WITH_VARS10(F) TYPES_WITH_VARS9(F), TYPE_WITH_VAR(F, 9)
169#define TYPES_WITH_VARS11(F) TYPES_WITH_VARS10(F), TYPE_WITH_VAR(F, 10)
170
171
172#define RET(F, ...) DefaultReturn<FuncInfo<decltype(F)>::Return>{__VA_ARGS__}
173
174#define DEFINE_FUNC(F, ArgsCount, /*Return value*/...)
175 DEFINE_FUNC_IMPL(F, VARS##ArgsCount, TYPES_WITH_VARS##ArgsCount, RET(F, __VA_ARGS__));
176
177#define DEFINE_IS_LOADED_CHECKER(FuncName) QT_BEGIN_NAMESPACE
178 bool
179 FuncName() { return SymbolsResolverImpl::instance().isLoaded(); } QT_END_NAMESPACE
180
181
182#define DECLARE_IS_LOADED_CHECKER(FuncName) QT_BEGIN_NAMESPACE
183 bool
184 FuncName(); QT_END_NAMESPACE
185
186
187// clang-format on
188
189#endif // Q_SYMBOLSRESOLVEUTILS
Combined button and popup list for selecting options.
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
#define VARS8()
#define RET(F,...)
#define TYPES_WITH_VARS1(F)
#define TYPES_WITH_VARS9(F)
#define VARS5()
QT_BEGIN_NAMESPACE constexpr bool areVersionsEqual(const char lhs[], const char rhs[])
#define VARS2()
#define VARS7()
#define TYPES_WITH_VARS3(F)
#define TYPES_WITH_VARS10(F)
#define VARS4()
#define EXPORT_FUNC
#define TYPES_WITH_VARS4(F)
#define TYPES_WITH_VARS6(F)
#define VARS6()
#define VARS1()
#define TYPE_WITH_VAR(F, I)
#define VARS9()
#define DEFINE_FUNC_IMPL(F, Vars, TypesWithVars, ReturnFunc)
#define VARS3()
#define VARS10()
#define TYPES_WITH_VARS7(F)
#define TYPES_WITH_VARS2(F)
#define TYPES_WITH_VARS8(F)
#define TYPES_WITH_VARS5(F)
constexpr bool areVersionsEqual(const char lhs[], int rhsInt)
#define VAR(I)
std::tuple< A... > Args