summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
committermanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
commitbe933ef2241d79558f91796cc5b3a161f72ebf9c (patch)
treefe3ab2f130e20c99001f2d7a81d610c78c96a3f4 /xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h
parent5f8335c1e49ce108ef3481863833c98efa00411b (diff)
downloadkodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.gz
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.bz2
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.zip
sync with upstream
Diffstat (limited to 'xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h')
-rw-r--r--xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h211
1 files changed, 211 insertions, 0 deletions
diff --git a/xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h b/xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h
new file mode 100644
index 0000000..3cc9eea
--- /dev/null
+++ b/xbmc/addons/kodi-dev-kit/include/kodi/tools/DllHelper.h
@@ -0,0 +1,211 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#pragma once
10
11#ifdef __cplusplus
12
13#include <string>
14
15#include <dlfcn.h>
16#include <kodi/AddonBase.h>
17#include <kodi/Filesystem.h>
18
19//==============================================================================
20/// @ingroup cpp_kodi_tools_CDllHelper
21/// @brief Macro to translate the given pointer value name of functions to
22/// requested function name.
23///
24/// @note This should always be used and does the work of
25/// @ref kodi::tools::CDllHelper::RegisterSymbol().
26///
27#define REGISTER_DLL_SYMBOL(functionPtr) \
28 kodi::tools::CDllHelper::RegisterSymbol(functionPtr, #functionPtr)
29//------------------------------------------------------------------------------
30
31namespace kodi
32{
33namespace tools
34{
35
36//==============================================================================
37/// @defgroup cpp_kodi_tools_CDllHelper class CDllHelper
38/// @ingroup cpp_kodi_tools
39/// @brief **Class to help with load of shared library functions**\n
40/// You can add them as parent to your class and to help with load of shared
41/// library functions.
42///
43/// @note To use on Windows must you also include [dlfcn-win32](https://github.com/dlfcn-win32/dlfcn-win32)
44/// on your addon!\n\n
45/// Furthermore, this allows the use of Android where the required library is
46/// copied to an EXE useable folder.
47///
48///
49/// ----------------------------------------------------------------------------
50///
51/// **Example:**
52/// ~~~~~~~~~~~~~{.cpp}
53///
54/// #include <kodi/tools/DllHelper.h>
55///
56/// ...
57/// class CMyInstance : public kodi::addon::CInstanceAudioDecoder,
58/// private kodi::tools::CDllHelper
59/// {
60/// public:
61/// CMyInstance(KODI_HANDLE instance, const std::string& kodiVersion);
62/// bool Start();
63///
64/// ...
65///
66/// // The pointers for on shared library exported functions
67/// int (*Init)();
68/// void (*Cleanup)();
69/// int (*GetLength)();
70/// };
71///
72/// CMyInstance::CMyInstance(KODI_HANDLE instance, const std::string& kodiVersion)
73/// : CInstanceAudioDecoder(instance, kodiVersion)
74/// {
75/// }
76///
77/// bool CMyInstance::Start()
78/// {
79/// std::string lib = kodi::GetAddonPath("myLib.so");
80/// if (!LoadDll(lib)) return false;
81/// if (!REGISTER_DLL_SYMBOL(Init)) return false;
82/// if (!REGISTER_DLL_SYMBOL(Cleanup)) return false;
83/// if (!REGISTER_DLL_SYMBOL(GetLength)) return false;
84///
85/// Init();
86/// return true;
87/// }
88/// ...
89/// ~~~~~~~~~~~~~
90///
91///@{
92class ATTRIBUTE_HIDDEN CDllHelper
93{
94public:
95 //============================================================================
96 /// @ingroup cpp_kodi_tools_CDllHelper
97 /// @brief Class constructor.
98 ///
99 CDllHelper() = default;
100 //----------------------------------------------------------------------------
101
102 //============================================================================
103 /// @ingroup cpp_kodi_tools_CDllHelper
104 /// @brief Class destructor.
105 ///
106 virtual ~CDllHelper()
107 {
108 if (m_dll)
109 dlclose(m_dll);
110 }
111 //----------------------------------------------------------------------------
112
113 //============================================================================
114 /// @ingroup cpp_kodi_tools_CDllHelper
115 /// @brief Function to load requested library.
116 ///
117 /// @param[in] path The path with filename of shared library to load
118 /// @return true if load was successful done
119 ///
120 bool LoadDll(std::string path)
121 {
122#if defined(TARGET_ANDROID)
123 if (kodi::vfs::FileExists(path))
124 {
125 // Check already defined for "xbmcaltbinaddons", if yes no copy necassary.
126 std::string xbmcaltbinaddons =
127 kodi::vfs::TranslateSpecialProtocol("special://xbmcaltbinaddons/");
128 if (path.compare(0, xbmcaltbinaddons.length(), xbmcaltbinaddons) != 0)
129 {
130 bool doCopy = true;
131 std::string dstfile = xbmcaltbinaddons + kodi::vfs::GetFileName(path);
132
133 kodi::vfs::FileStatus dstFileStat;
134 if (kodi::vfs::StatFile(dstfile, dstFileStat))
135 {
136 kodi::vfs::FileStatus srcFileStat;
137 if (kodi::vfs::StatFile(path, srcFileStat))
138 {
139 if (dstFileStat.GetSize() == srcFileStat.GetSize() &&
140 dstFileStat.GetModificationTime() > srcFileStat.GetModificationTime())
141 doCopy = false;
142 }
143 }
144
145 if (doCopy)
146 {
147 kodi::Log(ADDON_LOG_DEBUG, "Caching '%s' to '%s'", path.c_str(), dstfile.c_str());
148 if (!kodi::vfs::CopyFile(path, dstfile))
149 {
150 kodi::Log(ADDON_LOG_ERROR, "Failed to cache '%s' to '%s'", path.c_str(),
151 dstfile.c_str());
152 return false;
153 }
154 }
155
156 path = dstfile;
157 }
158 }
159 else
160 {
161 return false;
162 }
163#endif
164
165 m_dll = dlopen(path.c_str(), RTLD_LAZY);
166 if (m_dll == nullptr)
167 {
168 kodi::Log(ADDON_LOG_ERROR, "Unable to load %s", dlerror());
169 return false;
170 }
171 return true;
172 }
173 //----------------------------------------------------------------------------
174
175 //============================================================================
176 /// @ingroup cpp_kodi_tools_CDllHelper
177 /// @brief Function to register requested library symbol.
178 ///
179 /// @warning This function should not be used, use instead the macro
180 /// @ref REGISTER_DLL_SYMBOL to register the symbol pointer.
181 ///
182 ///
183 /// Use this always via Macro, e.g.:
184 /// ~~~~~~~~~~~~~{.cpp}
185 /// if (!REGISTER_DLL_SYMBOL(Init))
186 /// return false;
187 /// ~~~~~~~~~~~~~
188 ///
189 template <typename T>
190 bool RegisterSymbol(T& functionPtr, const char* strFunctionPtr)
191 {
192 functionPtr = reinterpret_cast<T>(dlsym(m_dll, strFunctionPtr));
193 if (functionPtr == nullptr)
194 {
195 kodi::Log(ADDON_LOG_ERROR, "Unable to assign function %s", dlerror());
196 return false;
197 }
198 return true;
199 }
200 //----------------------------------------------------------------------------
201
202private:
203 void* m_dll = nullptr;
204};
205///@}
206//------------------------------------------------------------------------------
207
208} /* namespace tools */
209} /* namespace kodi */
210
211#endif /* __cplusplus */