Mercurial > code
annotate C++/DynLib.cpp @ 263:fb91d4dc046b
Removal of Luae
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 14 Oct 2014 09:14:33 +0200 |
parents | d157f4747676 |
children | 24085fae3162 |
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 } |