1 /**
2 * Copyright 2021 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef MINDSPORE_CCSRC_CXX_API_DLUTILS_H_
17 #define MINDSPORE_CCSRC_CXX_API_DLUTILS_H_
18 #if !defined(_WIN32) && !defined(_WIN64)
19 #include <dlfcn.h>
20 #include <dirent.h>
21 #include <memory>
22 #include <string>
23 #include <fstream>
24 #include "utils/file_utils.h"
25
26 namespace mindspore {
DLSoPath(std::string * so_path)27 inline Status DLSoPath(std::string *so_path) {
28 if (so_path == nullptr) {
29 return Status(kMEFailed, "Input so_path can not be nullptr.");
30 }
31 Dl_info dl_info;
32 dladdr(reinterpret_cast<void *>(DLSoPath), &dl_info);
33 std::string libmindspore_so = dl_info.dli_fname;
34
35 auto pos = libmindspore_so.find("libmindspore.so");
36 if (pos == std::string::npos) {
37 return Status(kMEFailed, "Could not find libmindspore.so, check path.");
38 }
39
40 std::string parent_dir = libmindspore_so.substr(0, pos) + "../";
41 std::string c_dataengine_so;
42
43 DIR *dir = opendir(parent_dir.c_str());
44 if (dir != nullptr) {
45 // access all the files and directories within directory
46 dirent *ent = readdir(dir);
47 while (ent != nullptr) {
48 if (std::string(ent->d_name).find("_c_dataengine") != std::string::npos) {
49 c_dataengine_so = std::string(ent->d_name);
50 break;
51 }
52 ent = readdir(dir);
53 }
54 closedir(dir);
55 } else {
56 return Status(kMEFailed, "Could not open directory: " + parent_dir);
57 }
58
59 std::string unreal_path = parent_dir + c_dataengine_so;
60 auto realpath = FileUtils::GetRealPath(unreal_path.c_str());
61 if (!realpath.has_value()) {
62 return Status(kMEFailed, "Get c_dataengine_so real path failed, path: " + unreal_path);
63 }
64
65 *so_path = realpath.value();
66 return kSuccess;
67 }
68
DLSoOpen(const std::string & dl_path,const std::string & func_name,void ** handle,void ** function)69 inline Status DLSoOpen(const std::string &dl_path, const std::string &func_name, void **handle, void **function) {
70 // do dlopen and export functions from c_dataengine
71 *handle = dlopen(dl_path.c_str(), RTLD_LAZY | RTLD_LOCAL);
72
73 if (*handle == nullptr) {
74 return Status(kMEFailed, "dlopen failed, the pointer[handle] is null.");
75 }
76
77 *function = dlsym(*handle, func_name.c_str());
78 if (*function == nullptr) {
79 return Status(kMEFailed, "Could not find " + func_name + " in " + dl_path);
80 }
81 return kSuccess;
82 }
83
DLSoClose(void * handle)84 inline void DLSoClose(void *handle) {
85 if (handle != nullptr) {
86 (void)dlclose(handle);
87 }
88 }
89
90 #define CHECK_FAIL_AND_RELEASE(_s, _handle, _e) \
91 do { \
92 Status __rc = (_s); \
93 if (__rc.IsError()) { \
94 MS_LOG(ERROR) << (_e); \
95 DLSoClose((_handle)); \
96 return __rc; \
97 } \
98 } while (false)
99
100 } // namespace mindspore
101 #endif
102 #endif // MINDSPORE_CCSRC_CXX_API_DLUTILS_H_
103