ie_so_pointer.hpp
Go to the documentation of this file.
1 // Copyright (C) 2018-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 /**
6  * @brief This is a wrapper class for handling plugin instantiation and releasing resources
7  * @file ie_so_pointer.hpp
8  */
9 #pragma once
10 
11 #include <cassert>
12 #include <memory>
13 #include <string>
14 #include <type_traits>
15 
16 #include "ie_common.h"
17 #include "ie_so_loader.h"
18 #include "details/ie_exception.hpp"
20 #include "details/ie_irelease.hpp"
21 
22 namespace InferenceEngine {
23 namespace details {
24 
25 /**
26  * @brief This class is a C++ helper to load a symbol from a library and create its instance
27  */
28 template <class Loader>
29 class SymbolLoader {
30 private:
31  std::shared_ptr<Loader> _so_loader;
32 
33 public:
34  /**
35  * @brief The main constructor
36  * @param loader Library to load from
37  */
38  explicit SymbolLoader(std::shared_ptr<Loader> loader): _so_loader(loader) {
39  if (_so_loader == nullptr) {
40  THROW_IE_EXCEPTION << "SymbolLoader cannot be created with nullptr";
41  }
42  }
43 
44  /**
45  * @brief Calls a function from the library that creates an object and returns StatusCode
46  * @param name Name of function to load object with
47  * @return If StatusCode provided by function is OK then returns the loaded object. Throws an exception otherwise
48  */
49  template <class T>
50  T* instantiateSymbol(const std::string& name) const {
51  T* instance = nullptr;
52  ResponseDesc desc;
53  StatusCode sts = bind_function<StatusCode(T*&, ResponseDesc*)>(name)(instance, &desc);
54  if (sts != OK) {
56  }
57  return instance;
58  }
59 
60 private:
61  /**
62  * @brief Loads function from the library and returns a pointer to it
63  * @param functionName Name of function to load
64  * @return The loaded function
65  */
66  template <class T>
67  std::function<T> bind_function(const std::string& functionName) const {
68  std::function<T> ptr(reinterpret_cast<T*>(_so_loader->get_symbol(functionName.c_str())));
69  return ptr;
70  }
71 };
72 
73 /**
74  * @brief This class is a trait class that provides a creator with a function name corresponding to the templated class
75  * parameter
76  */
77 template <class T>
78 class SOCreatorTrait {};
79 
80 /**
81  * @brief Enables only `char` or `wchar_t` template specializations
82  * @tparam C A char type
83  */
84 template <typename C>
85 using enableIfSupportedChar = typename std::enable_if<(std::is_same<C, char>::value || std::is_same<C, wchar_t>::value)>::type;
86 
87 /**
88  * @brief This class instantiate object using shared library
89  * @tparam T An type of object SOPointer can hold
90  * @tparam Loader A loader used to load a library
91  */
92 template <class T, class Loader = SharedObjectLoader>
93 class SOPointer {
94  template <class U, class W>
95  friend class SOPointer;
96 
97 public:
98  /**
99  * @brief Default constructor
100  */
101  SOPointer() = default;
102 
103  /**
104  * @brief The main constructor
105  * @param name Name of a shared library file
106  */
107  template <typename C,
108  typename = enableIfSupportedChar<C>>
109  explicit SOPointer(const std::basic_string<C> & name)
110  : _so_loader(new Loader(name.c_str())),
111  _pointedObj(details::shared_from_irelease(
112  SymbolLoader<Loader>(_so_loader).template instantiateSymbol<T>(SOCreatorTrait<T>::name))) {}
113 
114  /**
115  * @brief The main constructor
116  * @param name Name of a shared library file
117  */
118  explicit SOPointer(const char * name)
119  : _so_loader(new Loader(name)),
120  _pointedObj(details::shared_from_irelease(
121  SymbolLoader<Loader>(_so_loader).template instantiateSymbol<T>(SOCreatorTrait<T>::name))) {}
122 
123  /**
124  * @brief Constructs an object with existing reference
125  * @param pointedObj Existing reference to wrap
126  */
127  explicit SOPointer(T* pointedObj): _so_loader(), _pointedObj(pointedObj) {
128  if (_pointedObj == nullptr) {
129  THROW_IE_EXCEPTION << "Cannot create SOPointer<T, Loader> from nullptr";
130  }
131  }
132 
133  /**
134  * @brief Constructs an object with existing loader
135  * @param so_loader Existing pointer to a library loader
136  */
137  explicit SOPointer(std::shared_ptr<Loader> so_loader)
138  : _so_loader(so_loader),
139  _pointedObj(details::shared_from_irelease(
140  SymbolLoader<Loader>(_so_loader).template instantiateSymbol<T>(SOCreatorTrait<T>::name))) {}
141 
142  /**
143  * @brief The copy-like constructor, can create So Pointer that dereferenced into child type if T is derived of U
144  * @param that copied SOPointer object
145  */
146  template <class U, class W>
147  SOPointer(const SOPointer<U, W>& that)
148  : _so_loader(std::dynamic_pointer_cast<Loader>(that._so_loader)),
149  _pointedObj(std::dynamic_pointer_cast<T>(that._pointedObj)) {
150  if (_pointedObj == nullptr) {
151  THROW_IE_EXCEPTION << "Cannot create object from SOPointer<U, W> reference";
152  }
153  }
154 
155  /**
156  * @brief Standard pointer operator
157  * @return underlined interface with disabled Release method
158  */
159  details::NoReleaseOn<T>* operator->() const noexcept {
160  return reinterpret_cast<details::NoReleaseOn<T>*>(_pointedObj.get());
161  }
162 
163  /**
164  * @brief Standard dereference operator
165  * @return underlined interface with disabled Release method
166  */
167  details::NoReleaseOn<T>* operator*() const noexcept {
168  return this->operator->();
169  }
170 
171  explicit operator bool() const noexcept {
172  return (nullptr != _so_loader) && (nullptr != _pointedObj);
173  }
174 
175  friend bool operator==(std::nullptr_t, const SOPointer& ptr) noexcept {
176  return !ptr;
177  }
178  friend bool operator==(const SOPointer& ptr, std::nullptr_t) noexcept {
179  return !ptr;
180  }
181  friend bool operator!=(std::nullptr_t, const SOPointer& ptr) noexcept {
182  return static_cast<bool>(ptr);
183  }
184  friend bool operator!=(const SOPointer& ptr, std::nullptr_t) noexcept {
185  return static_cast<bool>(ptr);
186  }
187 
188  SOPointer& operator=(const SOPointer& pointer) noexcept {
189  _pointedObj = pointer._pointedObj;
190  _so_loader = pointer._so_loader;
191  return *this;
192  }
193 
194  operator std::shared_ptr<Loader>() const noexcept {
195  return _so_loader;
196  }
197 
198 protected:
199  /**
200  * @brief Gets a smart pointer to the DLL
201  */
202  std::shared_ptr<Loader> _so_loader;
203 
204  /**
205  * @brief Gets a smart pointer to the custom object
206  */
207  std::shared_ptr<T> _pointedObj;
208 };
209 
210 } // namespace details
211 
212 /**
213  * @brief Creates a special shared_pointer wrapper for the given type from a specific shared module
214  * @tparam T An type of object SOPointer can hold
215  * @param name Name of the shared library file
216  * @return A created object
217  */
218 template <class T>
219 inline std::shared_ptr<T> make_so_pointer(const std::string & name) = delete;
220 
221 template <class T>
222 inline std::shared_ptr<T> make_so_pointer(const std::wstring & name) = delete;
223 
224 } // namespace InferenceEngine
This is a header file with common inference engine definitions.
A header file for the main Inference Engine exception.
#define THROW_IE_EXCEPTION
A macro used to throw general exception with a description.
Definition: ie_exception.hpp:25
A header file for the Inference Engine plugins destruction mechanism.
Utility header file. Provides no release base class.
A header file for definition of abstraction over platform specific shared objects.
Inference Engine C++ API.
Definition: cldnn_config.hpp:15
@ C
A bias layout for operation.
Definition: ie_common.h:82
std::shared_ptr< T > make_so_pointer(const std::string &name)=delete
Creates a special shared_pointer wrapper for the given type from a specific shared module.
Definition: ie_extension.h:115
StatusCode
This enum contains codes for all possible return values of the interface functions.
Definition: ie_common.h:224
char msg[256]
Definition: ie_c_api.h:123