1/*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
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
16#ifndef LBS_DYNAMIC_LOADER_H
17#define LBS_DYNAMIC_LOADER_H
18
19#include <dlfcn.h>
20
21#include "location_log.h"
22
23namespace OHOS {
24namespace Location {
25template<typename FuncType>
26class DynamicLibraryLoader {
27    typedef FuncType* (*funcEntry)();
28public:
29    explicit DynamicLibraryLoader(const std::string& libPath)
30    {
31        libPath_ = libPath;
32        handle_ = dlopen(libPath.c_str(), RTLD_LAZY);
33        if (!handle_) {
34            LBSLOGE(COMMON_UTILS, "%{public}s open so [%{public}s] failed, error: %{public}s",
35                __func__, libPath.c_str(), dlerror());
36        }
37        LBSLOGI(COMMON_UTILS, "%{public}s open so [%{public}s] success.", __func__, libPath.c_str());
38    }
39
40    ~DynamicLibraryLoader()
41    {
42        if (handle_) {
43            LBSLOGI(COMMON_UTILS, "%{public}s close so [%{public}s]", __func__, libPath_.c_str());
44#ifndef TEST_CASES_ENABLED
45            dlclose(handle_);
46            handle_ = nullptr;
47#endif
48        }
49    }
50
51    funcEntry GetFunction(const std::string& funcName)
52    {
53        if (!handle_) {
54            return nullptr;
55        }
56        auto funcPtr = dlsym(handle_, funcName.c_str());
57        char* error = dlerror();
58        if (error != nullptr || funcPtr == nullptr) {
59            LBSLOGE(COMMON_UTILS, "%{public}s, [%{public}s] dlsym error, error: %{public}s",
60                __func__, libPath_.c_str(), error);
61            return nullptr;
62        }
63        return (funcEntry)(funcPtr);
64    }
65
66private:
67    std::string libPath_;
68    void* handle_ = nullptr;
69};
70} // namespace Location
71} // namespace OHOS
72#endif // LBS_DYNAMIC_LOADER_H