4#ifndef Q_SYMBOLSRESOLVEUTILS
5#define Q_SYMBOLSRESOLVEUTILS
7#include <QtCore/qlibrary.h>
8#include <QtMultimedia/qtmultimediaexports.h>
28 return std::string_view(lhs) == std::string_view(rhs);
34 for (
int i = 0; lhs[i]; ++i) {
35 if (lhs[i] <
'0' || lhs[i] >
'9')
39 lhsInt += lhs[i] -
'0';
42 return lhsInt == rhsInt;
49 template <
typename... Arg>
57 template <
typename... Arg>
64template <
typename R,
typename... A>
74 using LibraryLoader = std::unique_ptr<QLibrary> (*)();
75 static bool isLazyLoadEnabled();
76 bool isLoaded()
const {
return m_library !=
nullptr; }
80 SymbolsResolver(
const char *libLoggingName, LibraryLoader loader);
82 SymbolsResolver(
const char *libName,
const char *version =
"",
83 const char *libLoggingName =
nullptr);
85 QFunctionPointer initOptionalFunction(
const char *name);
86 QFunctionPointer initFunction(
const char *name);
88 struct SymbolsMarker {};
89 void checkLibrariesLoaded(SymbolsMarker *begin, SymbolsMarker *end);
92 const char *m_libLoggingName;
93 std::unique_ptr<QLibrary> m_library;
101#define CHECK_VERSIONS(Name, NeededSoversion, DetectedVersion)
102 static_assert(areVersionsEqual(NeededSoversion, DetectedVersion),
103 "Configuartion error: misleading " Name " versions!")
105#define BEGIN_INIT_FUNCS(...)
108 class SymbolsResolverImpl : public SymbolsResolver {
110 SymbolsResolverImpl() : SymbolsResolver(__VA_ARGS__)
111 { checkLibrariesLoaded(&symbolsBegin, &symbolsEnd); }
112 static const SymbolsResolverImpl& instance()
113 { static const SymbolsResolverImpl instance; return instance; }
114 SymbolsMarker symbolsBegin;
116#define INIT_FUNC(F) QFunctionPointer F = initFunction(#F);
117#define INIT_OPT_FUNC(F) QFunctionPointer F = initOptionalFunction(#F);
119#define END_INIT_FUNCS()
120 SymbolsMarker symbolsEnd;
122 [[maybe_unused]] static const auto *instantResolver =
123 SymbolsResolver::isLazyLoadEnabled() ? &SymbolsResolverImpl::instance() : nullptr;
127#ifdef Q_EXPORT_STUB_SYMBOLS
128#define EXPORT_FUNC Q_MULTIMEDIA_EXPORT
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();
156#define TYPE_WITH_VAR(F, I) std::tuple_element_t<I, FuncInfo<decltype(F)>::Args> VAR(I)
157#define TYPES_WITH_VARS0(F)
171#define RET(F, ...) DefaultReturn<FuncInfo<decltype(F)>::Return>{__VA_ARGS__}
173#define DEFINE_FUNC(F, ArgsCount, ...)
176#define DEFINE_IS_LOADED_CHECKER(FuncName) QT_BEGIN_NAMESPACE
178 FuncName() { return SymbolsResolverImpl::instance().isLoaded(); } QT_END_NAMESPACE
181#define DECLARE_IS_LOADED_CHECKER(FuncName) QT_BEGIN_NAMESPACE
183 FuncName(); QT_END_NAMESPACE
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_STATIC_LOGGING_CATEGORY(name,...)
#define TYPES_WITH_VARS1(F)
#define TYPES_WITH_VARS9(F)
QT_BEGIN_NAMESPACE constexpr bool areVersionsEqual(const char lhs[], const char rhs[])
#define TYPES_WITH_VARS3(F)
#define TYPES_WITH_VARS10(F)
#define TYPES_WITH_VARS4(F)
#define TYPES_WITH_VARS6(F)
#define TYPE_WITH_VAR(F, I)
#define DEFINE_FUNC_IMPL(F, Vars, TypesWithVars, ReturnFunc)
#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)
void operator()(Arg &&...)