VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / utils / CarlaLibUtils.hpp
blob44746260bda5e2daf45ab9d960c43f122efc14ca
1 /*
2 * Carla library utils
3 * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
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.
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.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_LIB_UTILS_HPP_INCLUDED
19 #define CARLA_LIB_UTILS_HPP_INCLUDED
21 #include "CarlaUtils.hpp"
23 #ifdef CARLA_OS_WIN
24 typedef HMODULE lib_t;
25 #else
26 # include <dlfcn.h>
27 typedef void* lib_t;
28 #endif
30 // -----------------------------------------------------------------------
31 // library related calls
34 * Open 'filename' library (must not be null).
35 * May return null, in which case "lib_error" has the error.
37 static inline
38 lib_t lib_open(const char* const filename, const bool global = false) noexcept
40 CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
42 try {
43 #ifdef CARLA_OS_WIN
44 return ::LoadLibraryA(filename);
45 // unused
46 (void)global;
47 #else
48 return ::dlopen(filename, RTLD_NOW|(global ? RTLD_GLOBAL : RTLD_LOCAL));
49 #endif
50 } CARLA_SAFE_EXCEPTION_RETURN("lib_open", nullptr);
54 * Close a previously opened library (must not be null).
55 * If false is returned, "lib_error" has the error.
57 static inline
58 bool lib_close(const lib_t lib) noexcept
60 CARLA_SAFE_ASSERT_RETURN(lib != nullptr, false);
62 try {
63 #ifdef CARLA_OS_WIN
64 return ::FreeLibrary(lib);
65 #else
66 return (::dlclose(lib) == 0);
67 #endif
68 } CARLA_SAFE_EXCEPTION_RETURN("lib_close", false);
72 * Get a library symbol (must not be null) as a function.
73 * Returns null if the symbol is not found.
75 template<typename Func>
76 static inline
77 Func lib_symbol(const lib_t lib, const char* const symbol) noexcept
79 CARLA_SAFE_ASSERT_RETURN(lib != nullptr, nullptr);
80 CARLA_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', nullptr);
82 try {
83 #ifdef CARLA_OS_WIN
84 # if defined(__GNUC__) && (__GNUC__ >= 9)
85 # pragma GCC diagnostic push
86 # pragma GCC diagnostic ignored "-Wcast-function-type"
87 # endif
88 return reinterpret_cast<Func>(::GetProcAddress(lib, symbol));
89 # if defined(__GNUC__) && (__GNUC__ >= 9)
90 # pragma GCC diagnostic pop
91 # endif
92 #else
93 return reinterpret_cast<Func>(::dlsym(lib, symbol));
94 #endif
95 } CARLA_SAFE_EXCEPTION_RETURN("lib_symbol", nullptr);
99 * Return the last operation error ('filename' must not be null).
100 * May return null.
102 static inline
103 const char* lib_error(const char* const filename) noexcept
105 CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
107 #ifdef CARLA_OS_WIN
108 static char libError[2048+1];
109 carla_zeroChars(libError, 2048+1);
111 try {
112 const DWORD winErrorCode = ::GetLastError();
113 const int winErrorFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS;
114 LPVOID winErrorString;
116 ::FormatMessage(winErrorFlags, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);
118 std::snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString);
119 ::LocalFree(winErrorString);
120 } CARLA_SAFE_EXCEPTION("lib_error");
122 return (libError[0] != '\0') ? libError : nullptr;
123 #else
124 return ::dlerror();
125 #endif
128 // -----------------------------------------------------------------------
130 #endif // CARLA_LIB_UTILS_HPP_INCLUDED