Audio plugin host https://kx.studio/carla
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.

131 lines
3.8KB

  1. /*
  2. * Carla library utils
  3. * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_LIB_UTILS_HPP_INCLUDED
  18. #define CARLA_LIB_UTILS_HPP_INCLUDED
  19. #include "CarlaUtils.hpp"
  20. #ifdef CARLA_OS_WIN
  21. typedef HMODULE lib_t;
  22. #else
  23. # include <dlfcn.h>
  24. typedef void* lib_t;
  25. #endif
  26. // -----------------------------------------------------------------------
  27. // library related calls
  28. /*
  29. * Open 'filename' library (must not be null).
  30. * May return null, in which case "lib_error" has the error.
  31. */
  32. static inline
  33. lib_t lib_open(const char* const filename, const bool global = false) noexcept
  34. {
  35. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
  36. try {
  37. #ifdef CARLA_OS_WIN
  38. return ::LoadLibraryA(filename);
  39. // unused
  40. (void)global;
  41. #else
  42. return ::dlopen(filename, RTLD_NOW|(global ? RTLD_GLOBAL : RTLD_LOCAL));
  43. #endif
  44. } CARLA_SAFE_EXCEPTION_RETURN("lib_open", nullptr);
  45. }
  46. /*
  47. * Close a previously opened library (must not be null).
  48. * If false is returned, "lib_error" has the error.
  49. */
  50. static inline
  51. bool lib_close(const lib_t lib) noexcept
  52. {
  53. CARLA_SAFE_ASSERT_RETURN(lib != nullptr, false);
  54. try {
  55. #ifdef CARLA_OS_WIN
  56. return ::FreeLibrary(lib);
  57. #else
  58. return (::dlclose(lib) == 0);
  59. #endif
  60. } CARLA_SAFE_EXCEPTION_RETURN("lib_close", false);
  61. }
  62. /*
  63. * Get a library symbol (must not be null) as a function.
  64. * Returns null if the symbol is not found.
  65. */
  66. template<typename Func>
  67. static inline
  68. Func lib_symbol(const lib_t lib, const char* const symbol) noexcept
  69. {
  70. CARLA_SAFE_ASSERT_RETURN(lib != nullptr, nullptr);
  71. CARLA_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', nullptr);
  72. try {
  73. #ifdef CARLA_OS_WIN
  74. # if defined(__GNUC__) && (__GNUC__ >= 9)
  75. # pragma GCC diagnostic push
  76. # pragma GCC diagnostic ignored "-Wcast-function-type"
  77. # endif
  78. return reinterpret_cast<Func>(::GetProcAddress(lib, symbol));
  79. # if defined(__GNUC__) && (__GNUC__ >= 9)
  80. # pragma GCC diagnostic pop
  81. # endif
  82. #else
  83. return reinterpret_cast<Func>(::dlsym(lib, symbol));
  84. #endif
  85. } CARLA_SAFE_EXCEPTION_RETURN("lib_symbol", nullptr);
  86. }
  87. /*
  88. * Return the last operation error ('filename' must not be null).
  89. * May return null.
  90. */
  91. static inline
  92. const char* lib_error(const char* const filename) noexcept
  93. {
  94. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
  95. #ifdef CARLA_OS_WIN
  96. static char libError[2048+1];
  97. carla_zeroChars(libError, 2048+1);
  98. try {
  99. const DWORD winErrorCode = ::GetLastError();
  100. const int winErrorFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS;
  101. LPVOID winErrorString;
  102. ::FormatMessage(winErrorFlags, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);
  103. std::snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString);
  104. ::LocalFree(winErrorString);
  105. } CARLA_SAFE_EXCEPTION("lib_error");
  106. return (libError[0] != '\0') ? libError : nullptr;
  107. #else
  108. return ::dlerror();
  109. #endif
  110. }
  111. // -----------------------------------------------------------------------
  112. #endif // CARLA_LIB_UTILS_HPP_INCLUDED