Apache Mesos
dynamiclibrary.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_WINDOWS_DYNAMICLIBRARY_HPP__
14 #define __STOUT_WINDOWS_DYNAMICLIBRARY_HPP__
15 
16 #include <string>
17 
18 #include <stout/error.hpp>
19 #include <stout/nothing.hpp>
20 #include <stout/option.hpp>
21 #include <stout/stringify.hpp>
22 #include <stout/try.hpp>
23 
28 class DynamicLibrary
29 {
30 public:
31  DynamicLibrary() : handle_(nullptr) { }
32 
33  // Since this class manages a naked handle it cannot be copy- or
34  // move-constructed.
35  // TODO(bbannier): Allow for move-construction.
36  DynamicLibrary(const DynamicLibrary&) = delete;
37  DynamicLibrary(DynamicLibrary&&) = delete;
38 
39  virtual ~DynamicLibrary()
40  {
41  if (handle_ != nullptr) {
42  close();
43  }
44  }
45 
46  Try<Nothing> open(const std::string& path)
47  {
48  // Check if we've already opened a library.
49  if (handle_ != nullptr) {
50  return Error("Library already opened");
51  }
52 
53  handle_ = ::LoadLibraryW(wide_stringify(path).data());
54 
55  if (handle_ == nullptr) {
56  return WindowsError("Could not load library '" + path + "'");
57  }
58 
59  path_ = path;
60 
61  return Nothing();
62  }
63 
65  {
66  if (handle_ == nullptr) {
67  return Error("Could not close library; handle was already `nullptr`");
68  }
69 
70  if (!::FreeLibrary(handle_)) {
71  return WindowsError(
72  "Could not close library '" + (path_.isSome() ? path_.get() : ""));
73  }
74 
75  handle_ = nullptr;
76  path_ = None();
77 
78  return Nothing();
79  }
80 
81  Try<void*> loadSymbol(const std::string& name)
82  {
83  if (handle_ == nullptr) {
84  return Error(
85  "Could not get symbol '" + name + "'; library handle was `nullptr`");
86  }
87 
88  void* symbol = ::GetProcAddress(handle_, name.c_str());
89 
90  if (symbol == nullptr) {
91  return WindowsError(
92  "Error looking up symbol '" + name + "' in '" +
93  (path_.isSome() ? path_.get() : ""));
94  }
95 
96  return symbol;
97  }
98 
99 private:
100  HMODULE handle_;
101  Option<std::string> path_;
102 };
103 
104 #endif // __STOUT_WINDOWS_DYNAMICLIBRARY_HPP__
Definition: path.hpp:29
Try< Nothing > open(const std::string &path)
Definition: dynamiclibrary.hpp:46
Definition: nothing.hpp:16
Definition: errorbase.hpp:36
Definition: check.hpp:33
Definition: error.hpp:108
Try< void * > loadSymbol(const std::string &name)
Definition: dynamiclibrary.hpp:81
bool isSome() const
Definition: option.hpp:116
const T & get() const &
Definition: option.hpp:119
DynamicLibrary is a very simple wrapper around the programming interface to the dynamic linking loade...
Definition: dynamiclibrary.hpp:29
Definition: none.hpp:27
DynamicLibrary()
Definition: dynamiclibrary.hpp:31
Try< Nothing > close()
Definition: dynamiclibrary.hpp:62
virtual ~DynamicLibrary()
Definition: dynamiclibrary.hpp:39
constexpr const char * name
Definition: shell.hpp:41