| /* |
| * Copyright (C) 2022 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "Library" |
| #include <utils/Log.h> |
| #include <mediautils/Library.h> |
| |
| namespace { |
| |
| std::string dlerrorIfPresent() { |
| const char *dlerr = dlerror(); |
| if (dlerr == nullptr) return "dlerror: none"; |
| return std::string("dlerror: '").append(dlerr).append("'"); |
| } |
| |
| } |
| namespace android::mediautils { |
| |
| std::shared_ptr<void> loadLibrary(const char *libraryName, int flags) { |
| std::shared_ptr<void> library{ |
| dlopen(libraryName, flags), |
| [](void *lib) { |
| if (lib != nullptr) { |
| const int ret = dlclose(lib); |
| ALOGW_IF(ret !=0, "%s: dlclose(%p) == %d, %s", |
| __func__, lib, ret, dlerrorIfPresent().c_str()); |
| } |
| } |
| }; |
| |
| if (!library) { |
| ALOGW("%s: cannot load libraryName %s, %s", |
| __func__, libraryName, dlerrorIfPresent().c_str()); |
| return {}; |
| } |
| return library; |
| } |
| |
| std::shared_ptr<void> getUntypedObjectFromLibrary( |
| const char *objectName, const std::shared_ptr<void>& library) { |
| if (!library) { |
| ALOGW("%s: null library, cannot load objectName %s", __func__, objectName); |
| return {}; |
| } |
| void *ptr = dlsym(library.get(), objectName); |
| if (ptr == nullptr) { |
| ALOGW("%s: cannot load objectName %s, %s", |
| __func__, objectName, dlerrorIfPresent().c_str()); |
| return {}; |
| } |
| |
| // Note: we use the "aliasing" constructor of the std:shared_ptr. |
| // |
| // https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr |
| // |
| return { library, ptr }; // returns shared_ptr to ptr, but ref counted on library. |
| } |
| |
| } // namespace android::mediautils |