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