Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
dynamic_library.h
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_BASE_DYNAMIC_LIBRARY_H_
15#define OR_TOOLS_BASE_DYNAMIC_LIBRARY_H_
16
17#include <functional>
18#include <stdexcept>
19#include <string>
20
22
23#if defined(_MSC_VER)
24#define WIN32_LEAN_AND_MEAN // disables several conflicting macros
25#include <windows.h>
26#elif defined(__MINGW32__) || defined(__MINGW64__)
27#include <windows.h>
28#elif defined(__GNUC__)
29#include <dlfcn.h>
30#endif
31
33 public:
34 DynamicLibrary() : library_handle_(nullptr) {}
35
37 if (library_handle_ == nullptr) {
38 return;
39 }
40
41#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
42 FreeLibrary(static_cast<HINSTANCE>(library_handle_));
43#elif defined(__GNUC__)
44 dlclose(library_handle_);
45#endif
46 }
47
48 bool TryToLoad(const std::string& library_name) {
49 library_name_ = std::string(library_name);
50#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
51 library_handle_ = static_cast<void*>(LoadLibraryA(library_name.c_str()));
52#elif defined(__GNUC__)
53 library_handle_ = dlopen(library_name.c_str(), RTLD_NOW);
54#endif
55 return library_handle_ != nullptr;
56 }
57
58 bool LibraryIsLoaded() const { return library_handle_ != nullptr; }
59
60 template <typename T>
61 std::function<T> GetFunction(const char* function_name) {
62#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
63 // On Windows, avoid casting to void*: not supported by MinGW.
64 FARPROC function_address =
65 GetProcAddress(static_cast<HINSTANCE>(library_handle_), function_name);
66#else // Not Windows.
67 const void* function_address = dlsym(library_handle_, function_name);
68#endif // MinGW.
69
70 CHECK(function_address)
71 << "Error: could not find function " << std::string(function_name)
72 << " in " << library_name_;
73
74 return TypeParser<T>::CreateFunction(function_address);
75 }
76
77 template <typename T>
78 std::function<T> GetFunction(const std::string& function_name) {
79 return GetFunction<T>(function_name.c_str());
80 }
81
82 template <typename T>
83 void GetFunction(std::function<T>* function, const char* function_name) {
84 *function = GetFunction<T>(function_name);
85 }
86
87 template <typename T>
88 void GetFunction(std::function<T>* function,
89 const std::string function_name) {
90 GetFunction<T>(function, function_name.c_str());
91 }
92
93 private:
94 void* library_handle_ = nullptr;
95 std::string library_name_;
96
97 template <typename T>
98 struct TypeParser {};
99
100 template <typename Ret, typename... Args>
101 struct TypeParser<Ret(Args...)> {
102#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
103 // Windows: take a FARPROC as argument.
104 static std::function<Ret(Args...)> CreateFunction(
105 const FARPROC function_address) {
106 return std::function<Ret(Args...)>(
107 reinterpret_cast<Ret (*)(Args...)>(function_address));
108 }
109#else
110 // Not Windows: take a void* as argument.
111 static std::function<Ret(Args...)> CreateFunction(
112 const void* function_address) {
113 return std::function<Ret(Args...)>(reinterpret_cast<Ret (*)(Args...)>(
114 const_cast<void*>(function_address)));
115 }
116#endif
117 };
118};
119
120#endif // OR_TOOLS_BASE_DYNAMIC_LIBRARY_H_
void GetFunction(std::function< T > *function, const std::string function_name)
bool LibraryIsLoaded() const
void GetFunction(std::function< T > *function, const char *function_name)
std::function< T > GetFunction(const char *function_name)
std::function< T > GetFunction(const std::string &function_name)
bool TryToLoad(const std::string &library_name)