OR-Tools  9.0
dynamic_library.h
Go to the documentation of this file.
1 // Copyright 2010-2021 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 
21 #include "ortools/base/logging.h"
22 
23 #if defined(_MSC_VER)
24 #define WIN32_LEAN_AND_MEAN // disables several conflicting macros
25 #include <windows.h>
26 #elif defined(__GNUC__)
27 #include <dlfcn.h>
28 #endif
29 
31  public:
32  DynamicLibrary() : library_handle_(nullptr) {}
33 
35  if (library_handle_ == nullptr) {
36  return;
37  }
38 
39 #if defined(_MSC_VER)
40  FreeLibrary(static_cast<HINSTANCE>(library_handle_));
41 #elif defined(__GNUC__)
42  dlclose(library_handle_);
43 #endif
44  }
45 
46  bool TryToLoad(const std::string& library_name) {
47  library_name_ = std::string(library_name);
48 #if defined(_MSC_VER)
49  library_handle_ = static_cast<void*>(LoadLibrary(library_name.c_str()));
50 #elif defined(__GNUC__)
51  library_handle_ = dlopen(library_name.c_str(), RTLD_NOW);
52 #endif
53  return library_handle_ != nullptr;
54  }
55 
56  bool LibraryIsLoaded() const { return library_handle_ != nullptr; }
57 
58  template <typename T>
59  std::function<T> GetFunction(const char* function_name) {
60  const void* function_address =
61 #if defined(_MSC_VER)
62  static_cast<void*>(GetProcAddress(
63  static_cast<HINSTANCE>(library_handle_), function_name));
64 #else
65  dlsym(library_handle_, function_name);
66 #endif
67 
68  CHECK(function_address != nullptr)
69  << "Error: could not find function " << std::string(function_name)
70  << " in " << library_name_;
71 
72  return TypeParser<T>::CreateFunction(function_address);
73  }
74 
75  template <typename T>
76  std::function<T> GetFunction(const std::string& function_name) {
77  return GetFunction<T>(function_name.c_str());
78  }
79 
80  template <typename T>
81  void GetFunction(std::function<T>* function, const char* function_name) {
82  *function = GetFunction<T>(function_name);
83  }
84 
85  template <typename T>
86  void GetFunction(std::function<T>* function,
87  const std::string function_name) {
88  GetFunction<T>(function, function_name.c_str());
89  }
90 
91  private:
92  void* library_handle_ = nullptr;
93  std::string library_name_;
94 
95  template <typename T>
96  struct TypeParser {};
97 
98  template <typename Ret, typename... Args>
99  struct TypeParser<Ret(Args...)> {
100  static std::function<Ret(Args...)> CreateFunction(
101  const void* function_address) {
102  return std::function<Ret(Args...)>(reinterpret_cast<Ret (*)(Args...)>(
103  const_cast<void*>(function_address)));
104  }
105  };
106 };
107 
108 #endif // OR_TOOLS_BASE_DYNAMIC_LIBRARY_H_
#define CHECK(condition)
Definition: base/logging.h:498
std::function< T > GetFunction(const char *function_name)
bool TryToLoad(const std::string &library_name)
void GetFunction(std::function< T > *function, const std::string function_name)
void GetFunction(std::function< T > *function, const char *function_name)
std::function< T > GetFunction(const std::string &function_name)
bool LibraryIsLoaded() const