DISTRHO Plugin Framework
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.

130 lines
3.9KB

  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. # include <winsock2.h>
  21. # include <windows.h>
  22. typedef HMODULE lib_t;
  23. #else
  24. # include <dlfcn.h>
  25. typedef void* lib_t;
  26. #endif
  27. // -----------------------------------------------------------------------
  28. // library related calls
  29. /*
  30. * Open 'filename' library (must not be null).
  31. * May return null, in which case "lib_error" has the error.
  32. */
  33. static inline
  34. lib_t lib_open(const char* const filename) noexcept
  35. {
  36. DISTRHO_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
  37. try {
  38. #ifdef DISTRHO_OS_WINDOWS
  39. return ::LoadLibraryA(filename);
  40. #else
  41. return ::dlopen(filename, RTLD_NOW|RTLD_LOCAL);
  42. #endif
  43. } DISTRHO_SAFE_EXCEPTION_RETURN("lib_open", nullptr);
  44. }
  45. /*
  46. * Close a previously opened library (must not be null).
  47. * If false is returned, "lib_error" has the error.
  48. */
  49. static inline
  50. bool lib_close(const lib_t lib) noexcept
  51. {
  52. DISTRHO_SAFE_ASSERT_RETURN(lib != nullptr, false);
  53. try {
  54. #ifdef DISTRHO_OS_WINDOWS
  55. return ::FreeLibrary(lib);
  56. #else
  57. return (::dlclose(lib) == 0);
  58. #endif
  59. } DISTRHO_SAFE_EXCEPTION_RETURN("lib_close", false);
  60. }
  61. /*
  62. * Get a library symbol (must not be null).
  63. * Returns null if the symbol is not found.
  64. */
  65. template<typename Func>
  66. static inline
  67. Func lib_symbol(const lib_t lib, const char* const symbol) noexcept
  68. {
  69. DISTRHO_SAFE_ASSERT_RETURN(lib != nullptr, nullptr);
  70. DISTRHO_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', nullptr);
  71. try {
  72. #ifdef DISTRHO_OS_WINDOWS
  73. # if defined(__GNUC__) && (__GNUC__ >= 9)
  74. # pragma GCC diagnostic push
  75. # pragma GCC diagnostic ignored "-Wcast-function-type"
  76. # endif
  77. return (Func)::GetProcAddress(lib, symbol);
  78. # if defined(__GNUC__) && (__GNUC__ >= 9)
  79. # pragma GCC diagnostic pop
  80. # endif
  81. #else
  82. return (Func)(uintptr_t)::dlsym(lib, symbol);
  83. #endif
  84. } DISTRHO_SAFE_EXCEPTION_RETURN("lib_symbol", nullptr);
  85. }
  86. /*
  87. * Return the last operation error ('filename' must not be null).
  88. * May return null.
  89. */
  90. static inline
  91. const char* lib_error(const char* const filename) noexcept
  92. {
  93. DISTRHO_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
  94. #ifdef DISTRHO_OS_WINDOWS
  95. static char libError[2048+1];
  96. std::memset(libError, 0, sizeof(libError));
  97. try {
  98. const DWORD winErrorCode = ::GetLastError();
  99. const int winErrorFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS;
  100. LPVOID winErrorString;
  101. ::FormatMessage(winErrorFlags, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);
  102. std::snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString);
  103. ::LocalFree(winErrorString);
  104. } DISTRHO_SAFE_EXCEPTION("lib_error");
  105. return (libError[0] != '\0') ? libError : nullptr;
  106. #else
  107. return ::dlerror();
  108. #endif
  109. }
  110. // -----------------------------------------------------------------------
  111. #endif // DISTRHO_LIBRARY_UTILS_HPP_INCLUDED