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
17 #ifndef MINDSPORE_CCSRC_UTILS_DLOPEN_MACRO_H
18 #define MINDSPORE_CCSRC_UTILS_DLOPEN_MACRO_H
19
20 #ifndef _WIN32
21 #include <dlfcn.h>
22 #else
23 #include <windows.h>
24 #undef ERROR
25 #undef SM_DEBUG
26 #undef Yield
27 #endif
28 #include <string>
29 #include <functional>
30 #include "utils/log_adapter.h"
31
32 #ifndef _WIN32
33 #define PORTABLE_EXPORT __attribute__((visibility("default")))
34 #else
35 #define PORTABLE_EXPORT __declspec(dllexport)
36 #endif
37
38 #define PLUGIN_METHOD(name, return_type, ...) \
39 extern "C" { \
40 PORTABLE_EXPORT return_type Plugin##name(__VA_ARGS__); \
41 } \
42 constexpr const char *k##name##Name = "Plugin" #name; \
43 using name##FunObj = std::function<return_type(__VA_ARGS__)>; \
44 using name##FunPtr = return_type (*)(__VA_ARGS__);
45
46 #define ORIGIN_METHOD(name, return_type, ...) \
47 extern "C" { \
48 return_type name(__VA_ARGS__); \
49 } \
50 constexpr const char *k##name##Name = #name; \
51 using name##FunObj = std::function<return_type(__VA_ARGS__)>; \
52 using name##FunPtr = return_type (*)(__VA_ARGS__);
53
GetDlErrorMsg()54 inline static std::string GetDlErrorMsg() {
55 #ifndef _WIN32
56 const char *result = dlerror();
57 return (result == nullptr) ? "Unknown" : result;
58 #else
59 return std::to_string(GetLastError());
60 #endif
61 }
62
63 template <class T>
DlsymWithCast(void * handle,const char * symbol_name)64 static T DlsymWithCast(void *handle, const char *symbol_name) {
65 #ifndef _WIN32
66 T symbol = reinterpret_cast<T>(reinterpret_cast<intptr_t>(dlsym(handle, symbol_name)));
67 #else
68 T symbol = reinterpret_cast<T>(GetProcAddress(reinterpret_cast<HINSTANCE__ *>(handle), symbol_name));
69 #endif
70 if (symbol == nullptr) {
71 MS_LOG(EXCEPTION) << "Dynamically load symbol " << symbol_name << " failed, result = " << GetDlErrorMsg();
72 }
73 return symbol;
74 }
75
76 #define DlsymFuncObj(func_name, plugin_handle) DlsymWithCast<func_name##FunPtr>(plugin_handle, k##func_name##Name);
77
78 template <class T>
DlsymAscend(void * handle,const char * symbol_name)79 static T DlsymAscend(void *handle, const char *symbol_name) {
80 T symbol = reinterpret_cast<T>(reinterpret_cast<intptr_t>(dlsym(handle, symbol_name)));
81 if (symbol == nullptr) {
82 MS_LOG(WARNING) << "Dynamically load symbol " << symbol_name << " failed, result = " << GetDlErrorMsg();
83 }
84 return symbol;
85 }
86
87 #define DlsymAscendFuncObj(func_name, plugin_handle) DlsymAscend<func_name##FunPtr>(plugin_handle, k##func_name##Name);
88 #endif // MINDSPORE_CCSRC_UTILS_DLOPEN_MACRO_H
89