annotate C++/DynLib.cpp @ 248:d157f4747676

Directory: fix _WIN32 DynLib: fix _WIN32
author David Demelier <markand@malikania.fr>
date Wed, 01 Oct 2014 14:37:42 +0200
parents 274b4f216e65
children 24085fae3162
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * DynLib.cpp -- portable shared library loader
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013 David Demelier <markand@malikania.fr>
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <stdexcept>
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
20
248
d157f4747676 Directory: fix _WIN32
David Demelier <markand@malikania.fr>
parents: 196
diff changeset
21 #if defined(_WIN32)
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 # include <Windows.h>
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #else
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 # include <dlfcn.h>
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #endif
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include "DynLib.h"
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
248
d157f4747676 Directory: fix _WIN32
David Demelier <markand@malikania.fr>
parents: 196
diff changeset
29 #if defined(_WIN32)
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
30
196
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
31 namespace {
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
32
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
33 std::string systemError()
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
34 {
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
35 LPSTR error = nullptr;
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
36 std::string errmsg = "Unknown error";
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
37
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
38 FormatMessageA(
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
39 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
40 NULL,
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
41 GetLastError(),
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
42 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
43 (LPSTR)&error, 0, NULL);
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
44
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
45 if (error) {
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
46 errmsg = std::string(error);
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
47 LocalFree(error);
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
48 }
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
49
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
50 return errmsg;
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
51 }
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
52
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
53 }
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
54
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 void DynLib::systemInit()
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 {
196
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
57 m_handle = nullptr;
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
59
196
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
60 DynLib::Handle DynLib::systemLoad(const std::string &path, Policy policy) const
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 {
196
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
62 Handle handle = LoadLibraryA(path.c_str());
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
63
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
64 if (handle == nullptr)
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
65 throw std::runtime_error(systemError());
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
66
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
67 return handle;
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
69
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 DynLib::Sym DynLib::systemSym(const std::string &name)
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 {
196
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
72 Sym sym;
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
73
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
74 if (m_handle == nullptr)
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
75 throw std::runtime_error("library not loaded");
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
76
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
77 sym = GetProcAddress(m_handle, name.c_str());
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
78 if (sym == nullptr)
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
79 throw std::out_of_range(systemError());
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
80
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
81 return sym;
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
83
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 void DynLib::systemClose()
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 {
196
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
86 if (m_handle != nullptr)
274b4f216e65 DynLib: Windows support complete
David Demelier <markand@malikania.fr>
parents: 195
diff changeset
87 FreeLibrary(m_handle);
195
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
89
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 #else
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
91
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 void DynLib::systemInit()
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 {
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 m_handle = nullptr;
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
96
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 DynLib::Handle DynLib::systemLoad(const std::string &path, Policy policy) const
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 {
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 int mode = (policy == Immediately) ? RTLD_NOW : RTLD_LAZY;
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 Handle handle;
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
101
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 handle = dlopen(path.c_str(), mode);
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 if (handle == nullptr)
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 throw std::runtime_error(dlerror());
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
105
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 return handle;
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
108
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 DynLib::Sym DynLib::systemSym(const std::string &name)
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 {
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 Sym sym;
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
112
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 if (m_handle == nullptr)
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 throw std::runtime_error("library not loaded");
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
115
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 sym = dlsym(m_handle, name.c_str());
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 if (sym == nullptr)
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 throw std::out_of_range(dlerror());
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
119
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 return sym;
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
122
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 void DynLib::systemClose()
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 {
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 if (m_handle != nullptr)
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 dlclose(m_handle);
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
128
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 #endif
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
130
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 DynLib::DynLib()
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 {
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 systemInit();
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
135
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 DynLib::DynLib(const std::string &path, Policy policy)
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 {
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 m_handle = systemLoad(path, policy);
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 }
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
140
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 DynLib::~DynLib()
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 {
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 systemClose();
42b77e0161d0 Add a dynamic library loader
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 }