* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ------------------------------------------------------------------------- */
#ifndef __FUNCTION_LOADER_H__
#define __FUNCTION_LOADER_H__
#include <mutex>
#include <memory>
#include <string>
#include <unordered_map>
namespace func_injection {
class FunctionLoader {
public:
explicit FunctionLoader(const std::string& name) noexcept;
~FunctionLoader();
void Set(const std::string& name);
void* Get(const std::string& name);
private:
mutable std::mutex mu_;
std::string fileName;
void* handle = nullptr;
mutable std::unordered_map<std::string, void*> registry;
};
namespace register_function {
class FunctionRegister {
public:
static FunctionRegister* GetInstance();
void Register(const std::string& name, ::std::unique_ptr<FunctionLoader>&& ptr);
void Register(const std::string& name, const std::string& funcName);
void* Get(const std::string& soName, const std::string& funcName);
private:
FunctionRegister() = default;
mutable std::mutex mu_;
mutable std::unordered_map<std::string, ::std::unique_ptr<FunctionLoader>> registry;
};
class FunctionRegisterBuilder {
public:
FunctionRegisterBuilder(const std::string& name, ::std::unique_ptr<FunctionLoader>&& ptr) noexcept;
FunctionRegisterBuilder(const std::string& soName, const std::string& funcName) noexcept;
};
}
#define CONCAT_IMPL(x, y) x##y
#define MACRO_CONCAT(x, y) CONCAT_IMPL(x, y)
#define REGISTER_LIBRARY(soName) \
static func_injection::register_function::FunctionRegisterBuilder \
MACRO_CONCAT(register_library, __COUNTER__)(soName, \
::std::unique_ptr<func_injection::FunctionLoader>(new func_injection::FunctionLoader(soName)))
#define REGISTER_FUNCTION(soName, funcName) \
static func_injection::register_function::FunctionRegisterBuilder \
register_function_##funcName(soName, #funcName)
#define GET_FUNCTION(soName, funcName) \
func_injection::register_function::FunctionRegister::GetInstance()->Get(soName, funcName)
}
#define FUNC_BODY(soName, funcName, suffix, ErrorRet, ...) \
using FuncType = decltype(&funcName##suffix); \
static FuncType func = nullptr; \
if (func == nullptr) { \
func = reinterpret_cast<FuncType>(GET_FUNCTION(soName, #funcName)); \
if (func == nullptr) { \
return ErrorRet; \
} \
} \
return func(__VA_ARGS__)
#endif