imate
C++/CUDA Reference
Loading...
Searching...
No Matches
dynamic_loading.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: Copyright 2021, Siavash Ameli <sameli@berkeley.edu>
3 * SPDX-License-Identifier: BSD-3-Clause
4 * SPDX-FileType: SOURCE
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the license found in the LICENSE.txt file in the root
8 * directory of this source tree.
9 */
10
11
12#ifndef _CUDA_DYNAMIC_LOADING_DYNAMIC_LOADING_H_
13#define _CUDA_DYNAMIC_LOADING_DYNAMIC_LOADING_H_
14
15
16// =======
17// Headers
18// =======
19
20#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && \
21 !defined(__CYGWIN__)
22 #include <windows.h> // HMODULE, TEXT, LoadLibrary, GetProcAddress
23#elif defined(__unix__) || defined(__unix) || \
24 (defined(__APPLE__) && defined(__MACH__))
25 #include <dlfcn.h> // dlopen, dlsym
26#else
27 #error "Unknown compiler"
28#endif
29#include <stdexcept> // std::runtime_error
30#include <sstream> // std::ostringstream
31
32
33// ===============
34// dynamic loading
35// ===============
36
78
79namespace dynamic_loading
80{
81 // ==================
82 // get library handle (unix)
83 // ==================
84
85 #if defined(__unix__) || defined(__unix) || \
86 (defined(__APPLE__) && defined(__MACH__))
96
97 static void* get_library_handle_unix(const char* lib_name)
98 {
99 void* handle = dlopen(lib_name, RTLD_LAZY);
100
101 if (!handle)
102 {
103 throw std::runtime_error(dlerror());
104 }
105
106 return handle;
107 }
108 #endif
109
110
111 // ==================
112 // get library handle (windows)
113 // ==================
114
115 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && \
116 !defined(__CYGWIN__)
126
127 static HMODULE get_library_handle_windows(const char* lib_name)
128 {
129 HMODULE handle = LoadLibrary(TEXT(lib_name));
130
131 if (!handle)
132 {
133 std::ostringstream oss;
134 oss << "Cannot load the shared library '" << lib_name << "'." \
135 << std::endl;
136 std::string message = oss.str();
137 throw std::runtime_error(message);
138 }
139
140 return handle;
141 }
142 #endif
143
144
145 // ===========
146 // load symbol
147 // ===========
148
162
163 template <typename Signature>
164 Signature load_symbol(
165 const char* lib_name,
166 const char* symbol_name)
167 {
168 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && \
169 !defined(__CYGWIN__)
170
171 HMODULE handle = get_library_handle_windows(lib_name);
172 FARPROC symbol = GetProcAddress(handle, symbol_name);
173
174 if (symbol == NULL)
175 {
176 std::ostringstream oss;
177 oss << "The symbol '" << symbol << "' is failed to load " \
178 << "from the shared library '" << lib_name << "'." \
179 << std::endl;
180 std::string message = oss.str();
181 throw std::runtime_error(message);
182 }
183
184 #elif defined(__unix__) || defined(__unix) || \
185 (defined(__APPLE__) && defined(__MACH__))
186
187 void* handle = get_library_handle_unix(lib_name);
188 void* symbol = dlsym(handle, symbol_name);
189
190 char *error = dlerror();
191 if (error != NULL)
192 {
193 throw std::runtime_error(dlerror());
194 }
195
196 #else
197 #error "Unknown compiler"
198 #endif
199
200
201 return reinterpret_cast<Signature>(symbol);
202 }
203
204} // namespace dynamic_loading
205
206#endif // _CUDA_DYNAMIC_LOADING_DYNAMIC_LOADING_H_
Dynamic loading of shared libraries using dlopen tool.
Signature load_symbol(const char *lib_name, const char *symbol_name)
Loads a symbol within a library and returns a pointer to the symbol (function pointer).