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 # if DAWN_PLATFORM_WINUWP
22 # include "common/WindowsUtils.h"
23 # endif
24 #elif DAWN_PLATFORM_POSIX
25 # include <dlfcn.h>
26 #else
27 # error "Unsupported platform for DynamicLib"
28 #endif
29
~DynamicLib()30 DynamicLib::~DynamicLib() {
31 Close();
32 }
33
DynamicLib(DynamicLib && other)34 DynamicLib::DynamicLib(DynamicLib&& other) {
35 std::swap(mHandle, other.mHandle);
36 }
37
operator =(DynamicLib && other)38 DynamicLib& DynamicLib::operator=(DynamicLib&& other) {
39 std::swap(mHandle, other.mHandle);
40 return *this;
41 }
42
Valid() const43 bool DynamicLib::Valid() const {
44 return mHandle != nullptr;
45 }
46
Open(const std::string & filename,std::string * error)47 bool DynamicLib::Open(const std::string& filename, std::string* error) {
48 #if DAWN_PLATFORM_WINDOWS
49 # if DAWN_PLATFORM_WINUWP
50 mHandle = LoadPackagedLibrary(UTF8ToWStr(filename.c_str()).c_str(), 0);
51 # else
52 mHandle = LoadLibraryA(filename.c_str());
53 # endif
54 if (mHandle == nullptr && error != nullptr) {
55 *error = "Windows Error: " + std::to_string(GetLastError());
56 }
57 #elif DAWN_PLATFORM_POSIX
58 mHandle = dlopen(filename.c_str(), RTLD_NOW);
59
60 if (mHandle == nullptr && error != nullptr) {
61 *error = dlerror();
62 }
63 #else
64 # error "Unsupported platform for DynamicLib"
65 #endif
66
67 return mHandle != nullptr;
68 }
69
Close()70 void DynamicLib::Close() {
71 if (mHandle == nullptr) {
72 return;
73 }
74
75 #if DAWN_PLATFORM_WINDOWS
76 FreeLibrary(static_cast<HMODULE>(mHandle));
77 #elif DAWN_PLATFORM_POSIX
78 dlclose(mHandle);
79 #else
80 # error "Unsupported platform for DynamicLib"
81 #endif
82
83 mHandle = nullptr;
84 }
85
GetProc(const std::string & procName,std::string * error) const86 void* DynamicLib::GetProc(const std::string& procName, std::string* error) const {
87 void* proc = nullptr;
88
89 #if DAWN_PLATFORM_WINDOWS
90 proc = reinterpret_cast<void*>(GetProcAddress(static_cast<HMODULE>(mHandle), procName.c_str()));
91
92 if (proc == nullptr && error != nullptr) {
93 *error = "Windows Error: " + std::to_string(GetLastError());
94 }
95 #elif DAWN_PLATFORM_POSIX
96 proc = reinterpret_cast<void*>(dlsym(mHandle, procName.c_str()));
97
98 if (proc == nullptr && error != nullptr) {
99 *error = dlerror();
100 }
101 #else
102 # error "Unsupported platform for DynamicLib"
103 #endif
104
105 return proc;
106 }
107