library.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /************************************************************************************
  2. * *
  3. * Copyright (c) 2014 - 2018 Axel Menzel <info@rttr.org> *
  4. * *
  5. * This file is part of RTTR (Run Time Type Reflection) *
  6. * License: MIT License *
  7. * *
  8. * Permission is hereby granted, free of charge, to any person obtaining *
  9. * a copy of this software and associated documentation files (the "Software"), *
  10. * to deal in the Software without restriction, including without limitation *
  11. * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  12. * and/or sell copies of the Software, and to permit persons to whom the *
  13. * Software is furnished to do so, subject to the following conditions: *
  14. * *
  15. * The above copyright notice and this permission notice shall be included in *
  16. * all copies or substantial portions of the Software. *
  17. * *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
  24. * SOFTWARE. *
  25. * *
  26. *************************************************************************************/
  27. #ifndef RTTR_LIBRARY_H_
  28. #define RTTR_LIBRARY_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/type.h"
  31. #include <memory>
  32. namespace rttr
  33. {
  34. namespace detail
  35. {
  36. class library_private;
  37. } // end namespace detail
  38. /*!
  39. * The \ref library class provides a cross platform way of explicit loading shared objects
  40. * (`.so` on Unix based system and `.DLL` on windows).
  41. *
  42. * With a call to \ref load() the library will be loaded and with \ref unload() unloaded.
  43. * The explicit call to \ref unload() is not necessary. An internal ref count will trigger the unload automatically
  44. * on application exit. So you are free the let the \ref library instance go out of scope after loading,
  45. * the type data will still be available.
  46. *
  47. * After loading the library, the types of the plugin will be registered to the type system of RTTR.
  48. * Use therefore the macro: \ref RTTR_PLUGIN_REGISTRATION.
  49. * The \ref type "types" or global \ref property "properties" or \ref method "methods"
  50. * can be retrieved directly from the library class via getters.
  51. *
  52. * Because the types are registered via RTTR, it is not necessary to additionally mark your
  53. * types for export (e.g. using `__declspec( dllexport )` on windows).
  54. * Furthermore, with using RTTR, it is possible to export overloaded methods (same name but different signature).
  55. *
  56. * Copying and Assignment
  57. * ----------------------
  58. * A \ref library object cannot be copied or assigned.
  59. *
  60. * Typical Usage
  61. * ----------------------
  62. * A typical usage example is the following:
  63. * Some cpp file in your plugin called: "MyPlugin":
  64. * \code{.cpp}
  65. * #include <rttr/registration>
  66. * struct Foo
  67. * {
  68. * void set_value(int v) { value = v; }
  69. * int get_value() const { return value; }
  70. * int value = 0;
  71. * };
  72. *
  73. * RTTR_PLUGIN_REGISTRATION
  74. * {
  75. * rttr::registration::class_<Foo>("Foo")
  76. * .constructor<>()
  77. * .property("value", &Foo::set_value, &Foo::get_value);
  78. * }
  79. *
  80. * \endcode
  81. *
  82. * Now in your application, which loads the plugin:
  83. * \code{.cpp}
  84. * library lib("MyPlugin"); // file suffix is not needed, will be automatically appended
  85. * lib.load();
  86. * auto t = type::get_by_name("Foo");
  87. * std::cout << t.get_name() << std::endl; // prints "Foo"
  88. * variant var = t.create();
  89. * auto value = t.set_property_value("value", var, 12);
  90. * std::cout << t.get_property_value("value", var).to_string() << std::endl; // prints "12"
  91. * \endcode
  92. */
  93. class RTTR_API library
  94. {
  95. public:
  96. /*!
  97. * \brief Constructs a library instance that will load the given library \p `file_name` and
  98. * an optional version number \p version.
  99. * The file name is expected to be encoded in UTF-8 format.
  100. *
  101. * It is recommend to omit the file suffix, the library class will automatically look for a file
  102. * with the native library suffix/prefix ( e.g. `lib`, `.so` on Unix, `.dylib` on macOS and iOS, and `.dll` on Windows)
  103. */
  104. library(string_view file_name, string_view version = string_view());
  105. /*!
  106. * \brief Destroys the library instance.
  107. *
  108. * \remark This will not \ref unload() "unload" the library.
  109. * However, on application exit, the library will be unloaded automatically.
  110. *
  111. * \see unload()
  112. */
  113. ~library();
  114. library(const library&) = delete;
  115. library& operator=(const library&) = delete;
  116. /*!
  117. * \brief Loads the library and returns `true`; otherwise `false.`
  118. * When the library could not be loaded, check the \ref get_error_string() "error string".
  119. *
  120. * \return `true` when the library was successfully loaded; otherwise `false`.
  121. *
  122. * \see unload(), get_error_string()
  123. */
  124. bool load();
  125. /*!
  126. * \brief Unloads the library.
  127. * On application exit this happens automatically, so usually you don't need to call this function.
  128. * When the same library is loaded multiple times, this call will not succeed before every library instance was unloaded.
  129. *
  130. * \remark When you unload the library, make sure you don't hold any data (methods, properties or variants etc...) anymore,
  131. * which was created by this library. Otherwise undefined behavior may occur (crash!).
  132. *
  133. * \return `true` when the library was successfully unloaded, otherwise `false`.
  134. *
  135. * \see load(), get_error_string()
  136. */
  137. bool unload();
  138. /*!
  139. * \brief Returns true if the library is loaded; otherwise returns false
  140. *
  141. * \return `true` when the library is loaded; otherwise `false`.
  142. *
  143. * \see load(), unload()
  144. */
  145. bool is_loaded() const RTTR_NOEXCEPT;
  146. /*!
  147. * \brief When the library was not yet \ref load() "loaded", the file name given in the constructor will be returned.
  148. * After a successful call to \ref load(), \ref get_file_name() returns the fully-qualified file name of the library,
  149. * including the absolute path to the library if one was given in the constructor.
  150. * e.g.
  151. * \code{.cpp}
  152. * library lib("MyPlugin"); // loading a windows DLL relative (actual name is MyPlugin.dll)
  153. * lib.load();
  154. * lib.get_file_name(); // returns "MyPlugin.dll"
  155. * \endcode
  156. *
  157. * \return `true` when the library is loaded; otherwise `false`.
  158. *
  159. * \see load(), unload()
  160. */
  161. string_view get_file_name() const RTTR_NOEXCEPT;
  162. /*!
  163. * \brief Returns a text string with the description of the last error that occurred.
  164. * The error string will be only set when the \ref load() "loading" or \ref unload() "unloading" fails.
  165. *
  166. * \return An error string. Empty when no error occurred.
  167. *
  168. * \see load(), unload()
  169. */
  170. string_view get_error_string() const RTTR_NOEXCEPT;
  171. /*!
  172. * \brief A range of all registered type in this library.
  173. *
  174. * \return A range of all loaded types. Or empty if no \ref type "types" were loaded.
  175. *
  176. * \see type
  177. */
  178. array_range<type> get_types() const RTTR_NOEXCEPT;
  179. /*!
  180. * \brief A range of all registered global \ref property "properties" in this library.
  181. *
  182. * \return A range of all loaded properties. Or empty if no \ref property "properties" were loaded.
  183. *
  184. * \see property
  185. */
  186. array_range<property> get_global_properties() const RTTR_NOEXCEPT;
  187. /*!
  188. * \brief A range of all registered global \ref method "methods" in this library.
  189. *
  190. * \return A range of all loaded methods. Or empty if no \ref method "methods" were loaded.
  191. *
  192. * \see method
  193. */
  194. array_range<method> get_global_methods() const RTTR_NOEXCEPT;
  195. private:
  196. std::shared_ptr<detail::library_private> m_pimpl;
  197. bool m_is_loaded;
  198. };
  199. } // end namespace rttr
  200. #endif // RTTR_LIBRARY_H_