• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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