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.

137 lines
4.0KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifndef DISTRHO_LIBRARY_UTILS_HPP_INCLUDED
  17. #define DISTRHO_LIBRARY_UTILS_HPP_INCLUDED
  18. #include "../DistrhoUtils.hpp"
  19. #ifdef DISTRHO_OS_WINDOWS
  20. # ifndef NOMINMAX
  21. # define NOMINMAX
  22. # endif
  23. # include <winsock2.h>
  24. # include <windows.h>
  25. typedef HMODULE lib_t;
  26. #else
  27. # include <dlfcn.h>
  28. typedef void* lib_t;
  29. #endif
  30. START_NAMESPACE_DISTRHO
  31. // -----------------------------------------------------------------------
  32. // library related calls
  33. /*
  34. * Open 'filename' library (must not be null).
  35. * May return null, in which case "lib_error" has the error.
  36. */
  37. static inline
  38. lib_t lib_open(const char* const filename) noexcept
  39. {
  40. DISTRHO_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
  41. try {
  42. #ifdef DISTRHO_OS_WINDOWS
  43. return ::LoadLibraryA(filename);
  44. #else
  45. return ::dlopen(filename, RTLD_NOW|RTLD_LOCAL);
  46. #endif
  47. } DISTRHO_SAFE_EXCEPTION_RETURN("lib_open", nullptr);
  48. }
  49. /*
  50. * Close a previously opened library (must not be null).
  51. * If false is returned, "lib_error" has the error.
  52. */
  53. static inline
  54. bool lib_close(const lib_t lib) noexcept
  55. {
  56. DISTRHO_SAFE_ASSERT_RETURN(lib != nullptr, false);
  57. try {
  58. #ifdef DISTRHO_OS_WINDOWS
  59. return ::FreeLibrary(lib);
  60. #else
  61. return (::dlclose(lib) == 0);
  62. #endif
  63. } DISTRHO_SAFE_EXCEPTION_RETURN("lib_close", false);
  64. }
  65. /*
  66. * Get a library symbol (must not be null).
  67. * Returns null if the symbol is not found.
  68. */
  69. template<typename Func>
  70. static inline
  71. Func lib_symbol(const lib_t lib, const char* const symbol) noexcept
  72. {
  73. DISTRHO_SAFE_ASSERT_RETURN(lib != nullptr, nullptr);
  74. DISTRHO_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', nullptr);
  75. try {
  76. #ifdef DISTRHO_OS_WINDOWS
  77. # if defined(__GNUC__) && (__GNUC__ >= 9)
  78. # pragma GCC diagnostic push
  79. # pragma GCC diagnostic ignored "-Wcast-function-type"
  80. # endif
  81. return (Func)::GetProcAddress(lib, symbol);
  82. # if defined(__GNUC__) && (__GNUC__ >= 9)
  83. # pragma GCC diagnostic pop
  84. # endif
  85. #else
  86. return (Func)(uintptr_t)::dlsym(lib, symbol);
  87. #endif
  88. } DISTRHO_SAFE_EXCEPTION_RETURN("lib_symbol", nullptr);
  89. }
  90. /*
  91. * Return the last operation error ('filename' must not be null).
  92. * May return null.
  93. */
  94. static inline
  95. const char* lib_error(const char* const filename) noexcept
  96. {
  97. DISTRHO_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
  98. #ifdef DISTRHO_OS_WINDOWS
  99. static char libError[2048+1];
  100. std::memset(libError, 0, sizeof(libError));
  101. try {
  102. const DWORD winErrorCode = ::GetLastError();
  103. const int winErrorFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS;
  104. LPVOID winErrorString;
  105. ::FormatMessage(winErrorFlags, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);
  106. std::snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString);
  107. ::LocalFree(winErrorString);
  108. } DISTRHO_SAFE_EXCEPTION("lib_error");
  109. return (libError[0] != '\0') ? libError : nullptr;
  110. #else
  111. return ::dlerror();
  112. #endif
  113. }
  114. // -----------------------------------------------------------------------
  115. END_NAMESPACE_DISTRHO
  116. #endif // DISTRHO_LIBRARY_UTILS_HPP_INCLUDED