1 // Copyright (C) 2014 The Android Open Source Project
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "emugl/common/shared_library.h"
29 SharedLibrary* SharedLibrary::open(const char* libraryName) {
31 return open(libraryName, error, sizeof(error));
37 SharedLibrary* SharedLibrary::open(const char* libraryName,
40 HMODULE lib = LoadLibrary(libraryName);
42 return new SharedLibrary(lib);
49 // Convert error into human-readable message.
50 DWORD errorCode = ::GetLastError();
52 size_t messageLen = FormatMessageA(
53 FORMAT_MESSAGE_ALLOCATE_BUFFER |
54 FORMAT_MESSAGE_FROM_SYSTEM |
55 FORMAT_MESSAGE_IGNORE_INSERTS,
58 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
63 int ret = snprintf(error, errorSize, "%.*s", (int)messageLen, message);
64 if (ret < 0 || ret == static_cast<int>(errorSize)) {
65 // snprintf() on Windows doesn't behave as expected by C99,
66 // this path is to ensure that the result is always properly
68 ret = static_cast<int>(errorSize - 1);
71 // Remove any trailing \r\n added by FormatMessage
72 if (ret > 0 && error[ret - 1] == '\n') {
75 if (ret > 0 && error[ret - 1] == '\r') {
81 SharedLibrary::SharedLibrary(HandleType lib) : mLib(lib) {}
83 SharedLibrary::~SharedLibrary() {
89 SharedLibrary::FunctionPtr SharedLibrary::findSymbol(
90 const char* symbolName) const {
91 if (!mLib || !symbolName) {
94 return reinterpret_cast<FunctionPtr>(
95 GetProcAddress(mLib, symbolName));
101 SharedLibrary* SharedLibrary::open(const char* libraryName,
104 const char* libPath = libraryName;
107 const char* libBaseName = strrchr(libraryName, '/');
109 libBaseName = libraryName;
112 if (!strchr(libBaseName, '.')) {
113 // There is no extension in this library name, so append one.
115 static const char kDllExtension[] = ".dylib";
117 static const char kDllExtension[] = ".so";
119 size_t pathLen = strlen(libraryName) + sizeof(kDllExtension);
120 path = static_cast<char*>(malloc(pathLen));
121 snprintf(path, pathLen, "%s%s", libraryName, kDllExtension);
125 dlerror(); // clear error.
128 // On OSX, some libraries don't include an extension (notably OpenGL)
129 // On OSX we try to open |libraryName| first. If that doesn't exist,
130 // we try |libraryName|.dylib
131 void* lib = dlopen(libraryName, RTLD_NOW);
133 lib = dlopen(libPath, RTLD_NOW);
136 void* lib = dlopen(libPath, RTLD_NOW);
144 return new SharedLibrary(lib);
147 snprintf(error, errorSize, "%s", dlerror());
151 SharedLibrary::SharedLibrary(HandleType lib) : mLib(lib) {}
153 SharedLibrary::~SharedLibrary() {
159 SharedLibrary::FunctionPtr SharedLibrary::findSymbol(
160 const char* symbolName) const {
161 if (!mLib || !symbolName) {
164 return reinterpret_cast<FunctionPtr>(dlsym(mLib, symbolName));