1 // Copyright 2017 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "common/DynamicLib.h"
16
17 #include "common/Platform.h"
18
19 #if DAWN_PLATFORM_WINDOWS
20 # include "common/windows_with_undefs.h"
21 #elif DAWN_PLATFORM_POSIX
22 # include <dlfcn.h>
23 #else
24 # error "Unsupported platform for DynamicLib"
25 #endif
26
~DynamicLib()27 DynamicLib::~DynamicLib() {
28 Close();
29 }
30
DynamicLib(DynamicLib && other)31 DynamicLib::DynamicLib(DynamicLib&& other) {
32 std::swap(mHandle, other.mHandle);
33 }
34
operator =(DynamicLib && other)35 DynamicLib& DynamicLib::operator=(DynamicLib&& other) {
36 std::swap(mHandle, other.mHandle);
37 return *this;
38 }
39
Valid() const40 bool DynamicLib::Valid() const {
41 return mHandle != nullptr;
42 }
43
Open(const std::string & filename,std::string * error)44 bool DynamicLib::Open(const std::string& filename, std::string* error) {
45 #if DAWN_PLATFORM_WINDOWS
46 mHandle = LoadLibraryA(filename.c_str());
47
48 if (mHandle == nullptr && error != nullptr) {
49 *error = "Windows Error: " + std::to_string(GetLastError());
50 }
51 #elif DAWN_PLATFORM_POSIX
52 mHandle = dlopen(filename.c_str(), RTLD_NOW);
53
54 if (mHandle == nullptr && error != nullptr) {
55 *error = dlerror();
56 }
57 #else
58 # error "Unsupported platform for DynamicLib"
59 #endif
60
61 return mHandle != nullptr;
62 }
63
Close()64 void DynamicLib::Close() {
65 if (mHandle == nullptr) {
66 return;
67 }
68
69 #if DAWN_PLATFORM_WINDOWS
70 FreeLibrary(static_cast<HMODULE>(mHandle));
71 #elif DAWN_PLATFORM_POSIX
72 dlclose(mHandle);
73 #else
74 # error "Unsupported platform for DynamicLib"
75 #endif
76
77 mHandle = nullptr;
78 }
79
GetProc(const std::string & procName,std::string * error) const80 void* DynamicLib::GetProc(const std::string& procName, std::string* error) const {
81 void* proc = nullptr;
82
83 #if DAWN_PLATFORM_WINDOWS
84 proc = reinterpret_cast<void*>(GetProcAddress(static_cast<HMODULE>(mHandle), procName.c_str()));
85
86 if (proc == nullptr && error != nullptr) {
87 *error = "Windows Error: " + std::to_string(GetLastError());
88 }
89 #elif DAWN_PLATFORM_POSIX
90 proc = reinterpret_cast<void*>(dlsym(mHandle, procName.c_str()));
91
92 if (proc == nullptr && error != nullptr) {
93 *error = dlerror();
94 }
95 #else
96 # error "Unsupported platform for DynamicLib"
97 #endif
98
99 return proc;
100 }
101