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"
24 typedef HMODULE lib_t
;
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.
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);
44 return ::LoadLibraryA(filename
);
48 return ::dlopen(filename
, RTLD_NOW
|(global
? RTLD_GLOBAL
: RTLD_LOCAL
));
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.
58 bool lib_close(const lib_t lib
) noexcept
60 CARLA_SAFE_ASSERT_RETURN(lib
!= nullptr, false);
64 return ::FreeLibrary(lib
);
66 return (::dlclose(lib
) == 0);
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
>
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);
84 # if defined(__GNUC__) && (__GNUC__ >= 9)
85 # pragma GCC diagnostic push
86 # pragma GCC diagnostic ignored "-Wcast-function-type"
88 return reinterpret_cast<Func
>(::GetProcAddress(lib
, symbol
));
89 # if defined(__GNUC__) && (__GNUC__ >= 9)
90 # pragma GCC diagnostic pop
93 return reinterpret_cast<Func
>(::dlsym(lib
, symbol
));
95 } CARLA_SAFE_EXCEPTION_RETURN("lib_symbol", nullptr);
99 * Return the last operation error ('filename' must not be null).
103 const char* lib_error(const char* const filename
) noexcept
105 CARLA_SAFE_ASSERT_RETURN(filename
!= nullptr && filename
[0] != '\0', nullptr);
108 static char libError
[2048+1];
109 carla_zeroChars(libError
, 2048+1);
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;
128 // -----------------------------------------------------------------------
130 #endif // CARLA_LIB_UTILS_HPP_INCLUDED