Collection of DPF-based plugins for packaging
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
5.6KB

  1. //
  2. // ██████ ██  ██  ██████  ██████
  3. // ██      ██  ██ ██    ██ ██       ** Classy Header-Only Classes **
  4. // ██  ███████ ██  ██ ██
  5. // ██  ██   ██ ██  ██ ██ https://github.com/Tracktion/choc
  6. //  ██████ ██  ██  ██████   ██████
  7. //
  8. // CHOC is (C)2022 Tracktion Corporation, and is offered under the terms of the ISC license:
  9. //
  10. // Permission to use, copy, modify, and/or distribute this software for any purpose with or
  11. // without fee is hereby granted, provided that the above copyright notice and this permission
  12. // notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  13. // WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  14. // AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  15. // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  16. // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  17. // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. #ifndef CHOC_DYNAMIC_LIBRARY_HEADER_INCLUDED
  19. #define CHOC_DYNAMIC_LIBRARY_HEADER_INCLUDED
  20. #include <string>
  21. START_NAMESPACE_DISTRHO
  22. //==============================================================================
  23. /**
  24. A minimal cross-platform loader for .dll/.so files.
  25. */
  26. struct DynamicLibrary
  27. {
  28. DynamicLibrary() = default;
  29. /// Attempts to load a library with the given name or path.
  30. DynamicLibrary (std::string_view library);
  31. DynamicLibrary (const DynamicLibrary&) = delete;
  32. DynamicLibrary& operator= (const DynamicLibrary&) = delete;
  33. DynamicLibrary (DynamicLibrary&&);
  34. DynamicLibrary& operator= (DynamicLibrary&&);
  35. /// On destruction, this object releases the library that was loaded
  36. ~DynamicLibrary();
  37. /// Returns a pointer to the function with this name, or nullptr if not found.
  38. void* findFunction (std::string_view functionName);
  39. /// Returns true if the library was successfully loaded
  40. operator bool() const noexcept { return handle != nullptr; }
  41. /// Releases any handle that this object is holding
  42. void close();
  43. /// platform-specific handle. Will be nullptr if not loaded
  44. void* handle = nullptr;
  45. };
  46. //==============================================================================
  47. // _ _ _ _
  48. // __| | ___ | |_ __ _ (_)| | ___
  49. // / _` | / _ \| __| / _` || || |/ __|
  50. // | (_| || __/| |_ | (_| || || |\__ \ _ _ _
  51. // \__,_| \___| \__| \__,_||_||_||___/(_)(_)(_)
  52. //
  53. // Code beyond this point is implementation detail...
  54. //
  55. //==============================================================================
  56. inline DynamicLibrary::~DynamicLibrary()
  57. {
  58. close();
  59. }
  60. inline DynamicLibrary::DynamicLibrary (DynamicLibrary&& other) : handle (other.handle)
  61. {
  62. other.handle = nullptr;
  63. }
  64. inline DynamicLibrary& DynamicLibrary::operator= (DynamicLibrary&& other)
  65. {
  66. close();
  67. handle = other.handle;
  68. other.handle = nullptr;
  69. return *this;
  70. }
  71. //==============================================================================
  72. namespace win32_defs
  73. {
  74. #if ! (defined (_WINDOWS_) || defined (_APISETLIBLOADER_)) // only use these local definitions if windows.h isn't already included
  75. using CHOC_HMODULE = void*;
  76. #ifdef _MSC_VER
  77. extern "C" CHOC_HMODULE __stdcall choc_LoadLibraryA (const char*);
  78. extern "C" int __stdcall choc_FreeLibrary (CHOC_HMODULE);
  79. extern "C" void* __stdcall choc_GetProcAddress (CHOC_HMODULE, const char*);
  80. #pragma comment(linker,"/alternatename:choc_LoadLibraryA=LoadLibraryA")
  81. #pragma comment(linker,"/alternatename:choc_FreeLibrary=FreeLibrary")
  82. #pragma comment(linker,"/alternatename:choc_GetProcAddress=GetProcAddress")
  83. static inline CHOC_HMODULE LoadLibraryA (const char* l) { return choc_LoadLibraryA (l); }
  84. static inline int FreeLibrary (CHOC_HMODULE m) { return choc_FreeLibrary (m); }
  85. static inline void* GetProcAddress (CHOC_HMODULE m, const char* f) { return choc_GetProcAddress (m, f); }
  86. #else
  87. extern "C" __declspec(dllimport) CHOC_HMODULE __stdcall LoadLibraryA (const char*);
  88. extern "C" __declspec(dllimport) int __stdcall FreeLibrary (CHOC_HMODULE);
  89. extern "C" __declspec(dllimport) void* __stdcall GetProcAddress (CHOC_HMODULE, const char*);
  90. #endif
  91. #else
  92. using CHOC_HMODULE = HMODULE;
  93. static inline CHOC_HMODULE LoadLibraryA (const char* l) { return ::LoadLibraryA (l); }
  94. static inline int FreeLibrary (CHOC_HMODULE m) { return ::FreeLibrary (m); }
  95. static inline void* GetProcAddress (CHOC_HMODULE m, const char* f) { return (void*) ::GetProcAddress (m, f); }
  96. #endif
  97. }
  98. inline DynamicLibrary::DynamicLibrary (std::string_view library)
  99. {
  100. handle = (void*) win32_defs::LoadLibraryA (std::string (library).c_str());
  101. }
  102. inline void DynamicLibrary::close()
  103. {
  104. if (handle != nullptr)
  105. {
  106. win32_defs::FreeLibrary ((win32_defs::CHOC_HMODULE) handle);
  107. handle = nullptr;
  108. }
  109. }
  110. inline void* DynamicLibrary::findFunction (std::string_view name)
  111. {
  112. if (handle != nullptr)
  113. return (void*) win32_defs::GetProcAddress ((win32_defs::CHOC_HMODULE) handle, std::string (name).c_str());
  114. return {};
  115. }
  116. END_NAMESPACE_DISTRHO
  117. #endif // CHOC_DYNAMIC_LIBRARY_HEADER_INCLUDED