定义基类
#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);
适用于数据库填充和插件式开发等