美文网首页
c17++反射基类和使用

c17++反射基类和使用

作者: c之气三段 | 来源:发表于2023-08-25 21:38 被阅读0次

    定义基类

    #ifndef JOBJECT_H
    #define JOBJECT_H
    #include <functional>
    #include <map>
    #include <list>
    #include <any>
    
    
    class JObject
    {
    public:
        virtual ~JObject() {};
        virtual std::string className()
        {
            return m_className;
        }
        virtual void setclassName(std::string name)
        {
            m_className = name;
        }
        std::string m_className;
    };
    
    class JMeMberFunction
    {
    public:
        JMeMberFunction() = default;
    
        template<typename Class, typename... Args>
        explicit JMeMberFunction(void (Class::* func)(Args...))
        {
            function = [this, func](JObject* obj, void* arry)->std::any
            {
                Class* _cobj = dynamic_cast<Class*>(obj);
                auto tupe = (std::tuple<Args...>*)(arry);
                std::apply(func, std::tuple_cat(std::tuple<Class*>(_cobj), *tupe));
                return std::any{};
            };
        }
    
        template<typename Class, typename... Args>
        explicit JMeMberFunction(void (Class::* func)(Args...) const)
        {
            function = [this, func](JObject* obj, void* arry)->std::any
            {
                Class* _cobj = dynamic_cast<Class*>(obj);
                auto tupe = (std::tuple<Args...>*)(arry);
                std::apply(func, std::tuple_cat(std::tuple<Class*>(_cobj), *tupe));
                return std::any{};
            };
        }
    
        template<typename Class, typename Return, typename...Args>
        explicit JMeMberFunction(Return(Class::* func)(Args...))
        {
            function = [this, func](JObject* obj, void* arry)->std::any
            {
                Class* _cobj = dynamic_cast<Class*>(obj);
                auto tupe = (std::tuple<Args...>*)(arry);
                return std::apply(func, std::tuple_cat(std::tuple<Class*>(_cobj), *tupe));
            };
        }
    
        template<typename Class, typename Return, typename...Args>
        explicit JMeMberFunction(Return(Class::* func)(Args...) const)
        {
            function = [this, func](JObject* obj, void* arry)->std::any
            {
                Class* _cobj = dynamic_cast<Class*>(obj);
                auto tupe = (std::tuple<Args...>*)(arry);
                return std::apply(func, std::tuple_cat(std::tuple<Class*>(_cobj), *tupe));
            };
        }
    
        std::function<std::any(JObject* obj, void*)> function = nullptr;
    };
    
    class JMeMberVariable
    {
    public:
        JMeMberVariable() = default;
        explicit JMeMberVariable(std::string cdataType,std::any v)
        {
              variable = v;
              dataType = cdataType;
        }
        std::any variable;
        std::string dataType;
    };
    
    
    class JMetaObject
    {
    public:
    
        void registerFuction(std::string fucName, JMeMberFunction jMeMberFunction)
        {
            if (fucName.size() > 0)
            {
                if (fucName[0] == '&')
                {
                    int i = fucName.rfind(":");
                    if (i != std::string::npos) {
                        std::string s = fucName.substr(i + 1);
                        fucName = s;
                    }
                }
                m_JMemberFucs[fucName] = jMeMberFunction;
                m_JMemberFucNames.push_back(fucName);
            }
        }
    
        void registerVariable(std::string varName,JMeMberVariable jMeMberVariable)
        {
            if (varName.size() > 0)
            {
                if (varName[0] == '&')
                {
                    int i = varName.rfind(":");
                    if (i != std::string::npos) {
                        std::string s = varName.substr(i + 1);
                        int j = s.rfind(")");
                        if (j != std::string::npos)
                        {
                            s = s.substr(0,j);
                        }
                        varName = s;
                    }
                }
                m_JMembers[varName] = jMeMberVariable;
                m_JMemberMemberNames.push_back(varName);
            }
        }
    
        void getFuctionNames(std::vector<std::string>& fuctionNames)
        {
               fuctionNames =  m_JMemberFucNames;
        }
    
        void getVariableNames(std::vector<std::string>& variables)
        {
             variables = m_JMemberMemberNames;
        }
    
        std::vector<std::string> getFuctionNames()
        {
            return m_JMemberFucNames;
        }
    
        std::vector<std::string> getVariableNames()
        {
            return m_JMemberMemberNames;
        }
    
        template<typename... Args>
        std::any invoke(JObject* obj, std::string funcName, Args&&...args)
        {
            if (m_JMemberFucs.count(funcName) != 0)
            {
                auto tupe = std::make_tuple(std::forward<Args>(args)...);
                return m_JMemberFucs[funcName].function(obj, &tupe);
            }
            return std::any{};
        }
    
    
        std::any invokeGet(std::string varName)
        {
            if (m_JMembers.count(varName) != 0)
            {
                return  m_JMembers[varName].variable;
            }
            return nullptr;
        }
    
        template<typename T>
        void invokeSet(std::string varName,T var)
        {
            if (m_JMembers.count(varName) != 0)
            {
                *std::any_cast<T*>(m_JMembers[varName].variable) = var;
            }
        }
    
        std::string getMemberDataType(std::string variableName)
        {
            if(m_JMembers.count(variableName)==1)
            {
                return m_JMembers[variableName].dataType;
            }
            return "unknown";
        }
    
        std::string getMemberFuctionReturnDataType(std::string variableName)
        {
            if(m_JMembers.count(variableName)==1)
            {
                return m_JMembers[variableName].dataType;
            }
            return "unknown";
        }
    private:
        std::map<std::string, JMeMberFunction> m_JMemberFucs;
        std::map<std::string, JMeMberVariable> m_JMembers;
        std::vector<std::string>m_JMemberFucNames;
        std::vector<std::string>m_JMemberMemberNames;
    };
    
    
    class JReflectObject :public JObject
    {
    public:
        JReflectObject()
        {
    
        }
    
        virtual std::string className()
        {
            return m_className;
        }
    
        virtual void setclassName(std::string name)
        {
            m_className = name;
        }
    
        #define REGIST_FUNCTION(function)\
        metaObject.registerFuction(#function,JMeMberFunction(function));
    
        #define REGIST_VARIABLE(dataType,variable)\
        metaObject.registerVariable(#variable,JMeMberVariable(#dataType,variable));
    
        JMetaObject metaObject;
    };
    
    //int data = *(int*)(obj->metaObject.invokeGet(variables[i]));
    
    
    //必须实现的接口
    //extern "C" __declspec(dllexport) JObject * getInstance();
    //extern "C" __declspec(dllexport) void uninstallInstance();
    #endif // JOBJECT_H
    
    

    实现类继承插件类

    //.h中
    class xxx:public JPluginObject
    {
        xxx();
       bool a(int b,std::vector<int> &vec);
    std::string s;
    }
    //cpp中
    //构造函数中
    xxx::xxx()
    {
    REGIST_FUNCTION(&xxx::a);//注册成员函数
    REGIST_VARIABLE(string,&(xxx::s));//注册变量
    }
    //如果需要使用插件模式暴露给插件调用接口,需要放开c导出宏
    JObject* obj = nullptr;
    
    JObject* getInstance()
    {
        obj = new XXX;
        return obj;
    }
    
    void uninstallInstance()
    {
        if(obj)
        {
            delete obj;
            obj = nullptr;
        }
    }
    

    使用

    //插件模式时用法
        typedef JObject* (*Instance)();
        typedef void (*UninstallInstance)();
        std::string dllName;
        HINSTANCE handle;
        JObject* obj;
    
        handle= LoadLibraryA(dllName.c_str());
        if (handle== NULL)
        {
                    //
        }
        Instance instance = (Instance)GetProcAddress(handle, "getInstance");
        if (!instance)
        {
                  //
        }
        obj= instance();
    //正常使用
    int y = 5;
    std::vector<int> vec;
    vec.resize(4);
    if (obj)
        {
            JPluginObject* plginObj = dynamic_cast<JPluginObject*>(obj);
            plginObj->metaObject()->invoke(object, "XXX", y,vec); Call the function, pass parameters, and if there is a return value, you can catch and convert the result returned by type invoke
            std::string s = *std::any_cast<std::string*> (plginObj->metaObject()->invokeGet("s"));
            plginObj->metaObject()->invokeSet<std::string>("s","hello")
        }
    //卸载,插件模式时使用
        UninstallInstance uninstallInstance = (UninstallInstance)GetProcAddress(handle, "uninstallInstance");
        uninstallInstance();
        FreeLibrary(m_handle);
    

    适用于数据库填充和插件式开发等

    相关文章

      网友评论

          本文标题:c17++反射基类和使用

          本文链接:https://www.haomeiwen.com/subject/jrdsjdtx.html