C++ 动态反射 第一版

1:这个C++ 反射库功能比较少,但是使用起来比较简单。

2:功能:支持属性类型信息查看,属性值获取,属性值设置,成员函数反射,成员函数类型信息查看。

 1:Reflect.h

#ifndef REFLECT_H
#define REFLECT_H

#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>

#ifdef _WIN32
	#define REFLECT_EXPORT				__declspec(dllexport)
	//windows x86 or x68
	#ifdef _WIN64 //x64 windows
		typedef signed	long long		pointer_int;
	#else //x86 windows
		typedef signed	int				pointer_int;
	#endif //end of _WIN64
#else //unix
	#define REFLECT_EXPORT				
	#ifdef __x86_64__ //x64 unix
		typedef signed	long long		pointer_int;
	#elif __i386__ //x86 unix
		typedef signed	int				pointer_int;
	#endif //end of __x86_64__

#endif //end of _WIN32
#define LocalOffset(func) *(pointer_int*)((pointer_int)&func)
namespace Trds {
namespace Reflect {

class TrdsObject;

	// 是否启用C++17
#if __cplusplus >= 201703L
#define CPP_HAS_17 1
#endif
// Error id
constexpr int error_id_0_Unclear = 0;
constexpr int error_id_1_too_few_parameters = 1;
constexpr int error_id_2_too_many_parameters = 2;
constexpr int error_id_3_types_do_not_match = 3;

static const char* error_buffer[]
{
	"Unknown exception. Please carefully check whether the number of parameter bindings or the types of parameter bindings are correct. Note that the type of the incoming parameters needs to strictly correspond.",
	"Too few parameters are passed in",
	"Too many parameters are passed in",
	"The parameter types do not match"
};

class ICallBackException : public std::exception {
public:
	ICallBackException(int error_id = 0)
	{
		m_error_id = error_id;
	}

	virtual const char* what()const override
	{
		return error_buffer[m_error_id];
	}

private:
	int m_error_id{ 0 };
};

class CallBackExceptionUnClear : public ICallBackException
{
public:
	CallBackExceptionUnClear()
		:ICallBackException(error_id_0_Unclear)
	{

	}
};

class CallBackExceptionFewParameters : public ICallBackException
{
public:
	CallBackExceptionFewParameters()
		:ICallBackException(error_id_1_too_few_parameters)
	{

	}
};

class CallBackExceptionManyParameters : public ICallBackException
{
public:
	CallBackExceptionManyParameters()
		:ICallBackException(error_id_2_too_many_parameters)
	{

	}
};

class CallBackExceptionNotMatch : public ICallBackException
{
public:
	CallBackExceptionNotMatch()
		:ICallBackException(error_id_3_types_do_not_match)
	{

	}
};

template<typename T> struct Array { using type = T*; };
template<typename T> struct Array<T*> { using type = T(*)[1]; };
template<> struct Array<void*> { using type = void**; };
template<typename T> struct Array<T[]> { using type = T(*)[1]; };

template<typename T> struct function_traits;
template<typename R, typename ...Args>
struct function_traits<R(Args...)>
{
	enum
	{
		arity = sizeof...(Args)
	};
	static const  char* typeinfos[arity + 1];
	typedef R Ret;
	typedef R function(Args...);
	typedef R(*function_pointer)(Args...);
	using args_tuple_pointer = std::tuple<typename Array<std::remove_cv_t<std::remove_reference_t<Args>>>::type...>;
};
template<typename R, typename ...Args>
const char* function_traits<R(Args...)>::typeinfos[arity + 1] = { typeid(Args).name()... };

template<typename R, typename Type, typename ...Args> struct function_traits<R(Type::*)(Args...)> : public function_traits<R(Args...)> { using object = Type; using object_pointer = Type*; };
template<typename R, typename Type, typename ...Args> struct function_traits<R(Type::*)(Args...)const> : public function_traits<R(Args...)> { using object = Type; using object_pointer = Type*; };

class Object final
{
public:
	Object()
	{
		data_.reset();
	}

	template <typename T>
	Object(T* data, bool isHeap = true)
	{
		data_.reset(new ObjectTemplat<T>(data, isHeap));
	}

	template <typename T>
	Object(const T& data)
	{
		data_.reset(new ObjectTemplat<T>(data));
	}

	Object(const Object& rvalue) noexcept
	{
		data_ = rvalue.data_;
	}

	Object(Object&& rvalue) noexcept
	{
		data_.swap(const_cast<Object&>(rvalue).data_);
	}

	Object& operator=(const Object& rvalue) noexcept
	{
		data_ = rvalue.data_;
		return*this;
	}

	Object& operator=(Object&& rvalue) noexcept
	{
		data_.swap(const_cast<Object&>(rvalue).data_);
		return*this;
	}

	operator bool()const
	{
		return data_.get();
	}

	char* GetCharPtr()const
	{
		return data_->GetCharPtr();
	}

	template <typename T, typename U = char>
	T Value()
	{
		ObjectTemplat<U>* vptr = dynamic_cast<ObjectTemplat<U>*>(data_.get());
		return *(T*)vptr->Get();
	}

	class IBaseVlaue
	{
	public:
		virtual ~IBaseVlaue() = default;
		virtual char* GetCharPtr()const = 0;
	};

	template <typename T> class ObjectTemplat : public IBaseVlaue
	{
	public:
		ObjectTemplat(const T& data)
			: isHeap(true)
		{
#ifdef CPP_HAS_17
			if constexpr (std::is_void_v<T>)
			{
				data_ = data;
			}
			else
			{
#endif
				data_ = new T(data);
#ifdef CPP_HAS_17
			}
#endif
		}

		ObjectTemplat(const T* data)
			: isHeap(true)
		{
			data_ = const_cast<T*>(data);
		}

		ObjectTemplat(T* data, bool isHeap)
			: isHeap(isHeap), data_(data)
		{

		}

		~ObjectTemplat()
		{
			if (isHeap && data_)
			{
				delete data_;
			}
			data_ = nullptr;
		}

		virtual char* GetCharPtr()const
		{
			return reinterpret_cast<char*>(data_);
		}

		T* Get()
		{
			return data_;
		}
	private:
		bool isHeap;
		T* data_;
	};

	template <> class ObjectTemplat<void> : public IBaseVlaue
	{
	public:
		ObjectTemplat(void* data)
			: isHeap(true)
		{
			data_ = data;
		}

		ObjectTemplat(void* data, bool isHeap)
			: isHeap(isHeap), data_(data)
		{

		}

		~ObjectTemplat()
		{
			if (isHeap && data_)
			{
				::free(data_);
			}
			data_ = nullptr;
		}

		virtual char* GetCharPtr()const
		{
			return reinterpret_cast<char*>(data_);
		}

		void* Get()
		{
			return data_;
		}
	private:
		bool isHeap;
		void* data_;
	};

private:
	std::shared_ptr<IBaseVlaue> data_;
};

class MetaFunction
{
public:
	MetaFunction()
	{
		pBinder.reset();
		mObj = nullptr;
	}
	
	template <typename R, typename Cla, typename... Args>
	MetaFunction(const std::string& function_, R(Cla::* Call)(Args...))
	{
		pBinder.reset(new CPFunction<R(Cla::*)(Args...)>(function_, Call));
		mObj = nullptr;
	}

	template <typename R, typename Cla, typename... Args>
	MetaFunction(const std::string& function_, R(Cla::* Call)(Args...)const)
	{
		pBinder.reset(new CPFunction<R(Cla::*)(Args...)const>(function_, Call));
		mObj = nullptr;
	}


	MetaFunction(const MetaFunction& ot) noexcept
	{
		pBinder = ot.pBinder;
		mObj = ot.mObj;
	}

	MetaFunction(MetaFunction&& ot) noexcept
	{
		pBinder.swap(ot.pBinder);
		mObj = ot.mObj;
	}

	MetaFunction& operator=(const MetaFunction& ot) noexcept
	{
		pBinder = ot.pBinder;
		mObj = ot.mObj;
		return*this;
	}

	MetaFunction& operator=(MetaFunction&& ot) noexcept
	{
		pBinder.swap(ot.pBinder);
		mObj = ot.mObj;
		return*this;
	}
	
	void setTrdsObject(TrdsObject* obj_)
	{
		mObj = obj_;
	}

	std::string GetName()const
	{
		return pBinder->GetName();
	}

	int GetLocalOffset()const
	{
		return pBinder->GetLocalOffset();
	}

	template <typename... Args>
	Object operator()(Args&&... args) const& noexcept
	{
		auto& args_tuple = std::make_tuple(std::addressof(args)...);
		const char* in[] = { 0, typeid(Args).name()... };
		return pBinder->Call(mObj, &args_tuple, sizeof...(Args), in);
	}
	operator bool()
	{
		return pBinder.get() != nullptr;
	}

protected:
	class IBinderTemplate
	{
	private:
		const std::string mName;
		const pointer_int local_offset;

	public:
		IBinderTemplate(const std::string& mName, pointer_int local_offset) : mName(mName), local_offset(local_offset){}
		virtual Object Call(TrdsObject* mObj, void* args, int count, const char** in) = 0;
		int GetLocalOffset()const { return local_offset; }
		virtual std::string GetName()const
		{
			return mName;
		}

		void Check(const char** need, const char** real, int nneed, int nreal)
		{
			if (nneed < nreal)
			{
				throw CallBackExceptionManyParameters();
			}
			
			if (nneed > nreal)
			{
				throw CallBackExceptionFewParameters();
			}

			for (int index_ = 0; index_ < nreal; ++index_)
			{
				if (strcmp(real[index_ + 1], need[index_]) != 0)
				{
					throw CallBackExceptionNotMatch();
				}
			}
		}

		virtual ~IBinderTemplate()
		{

		}

#ifdef CPP_HAS_17

		template<typename RS, typename Function, typename Caller, typename Cla, size_t ...II>
		Object CallBack(void* args, Cla* obj, Caller& caller, const std::index_sequence<II...>&)
		{
			using tupleArgs = typename function_traits<Function>::args_tuple_pointer;
			tupleArgs& tuple = *reinterpret_cast<tupleArgs*>(args);

			if constexpr (std::is_void_v<RS>)
			{
				(obj->*caller)(*std::get<II>(tuple)...);
				return Object();
			}
			else
			{
				return (obj->*caller)(*std::get<II>(tuple)...);
			}
		}
	};

#else
	template<typename RS, typename Function, typename Caller, typename Cla, size_t ...II>
	Object CallBack(RS*&, void* args, Cla* obj, Caller& caller, const std::index_sequence<II...>&)
	{
		using tupleArgs = typename function_traits<Function>::args_tuple_pointer;
		tupleArgs& tuple = *reinterpret_cast<tupleArgs*>(args);

		return (obj->*caller)(*std::get<II>(tuple)...);
	}

	template<typename RS, typename Function, typename Caller, typename Cla, size_t ...II>
	Object CallBack(void*&, void* args, Cla* obj, Caller& caller, const std::index_sequence<II...>&)
	{
		using tupleArgs = typename function_traits<Function>::args_tuple_pointer;
		tupleArgs& tuple = *reinterpret_cast<tupleArgs*>(args);

		(obj->*caller)(*std::get<II>(tuple)...);
		return Object();
	}
};

#endif
	template <typename CallAble, typename... BindArgs> class CPFunction;

	template <typename R, typename Cla, typename... Args>
	class CPFunction<R(Cla::*)(Args...)> : public IBinderTemplate
	{
		using Function = R(Cla::*)(Args...);
	public:
		CPFunction(const std::string& function_, Function func)
			: mCall(func), IBinderTemplate(function_, LocalOffset(func))
		{

		}

		virtual Object Call(TrdsObject* mObj, void* args, int count, const char** in) override
		{
			Check(function_traits<Function>::typeinfos, in, function_traits<Function>::arity, count);
			using Ret = typename function_traits<Function>::Ret;
#ifdef CPP_HAS_17
			return CallBack<Ret, Function, Function, Cla>(args, dynamic_cast<Cla*>(mObj), mCall, std::make_index_sequence<function_traits<Function>::arity>());
#else
			Ret* temp = 0;
			return CallBack<Ret, Function, Function, Cla>(temp, args, dynamic_cast<Cla*>(mObj), mCall, std::make_index_sequence<function_traits<Function>::arity>());
#endif
		}

	private:
		Function mCall;
	};

	template <typename R, typename Cla, typename... Args>
	class CPFunction<R(Cla::*)(Args...)const> : public IBinderTemplate
	{
		using Function = R(Cla::*)(Args...)const;
	public:
		CPFunction(const std::string& function_, Function func)
			: mCall(func), IBinderTemplate(function_, LocalOffset(func))
		{

		}

		virtual Object Call(TrdsObject* mObj, void* args, int count, const char** in) override
		{
			Check(function_traits<Function>::typeinfos, in, function_traits<Function>::arity, count);
			using Ret = typename function_traits<Function>::Ret;
#ifdef CPP_HAS_17
			return CallBack<Ret, Function, Function, Cla>(args, dynamic_cast<Cla*>(mObj), mCall, std::make_index_sequence<function_traits<Function>::arity>());
#else
			Ret* temp = 0;
			return CallBack<Ret, Function, Function, Cla>(temp, args, dynamic_cast<Cla*>(mObj), mCall, std::make_index_sequence < function_traits<Function>::arity>());
#endif
		}

	private:
		Function mCall;
	};

private:
	std::shared_ptr<IBinderTemplate>	pBinder;
	TrdsObject*							mObj;
};


class Field;
class MetaObject;

class MetaObjectImpl;
class MetaImpl;
class FieldImpl;

using News = std::map<std::string, MetaFunction>;
using Invokes = std::map<std::string, std::vector<MetaFunction>>;
using Fields = std::map<std::string, std::vector<std::shared_ptr<Field>>>;
using MetaObjectPtr = std::shared_ptr<MetaObject>;
using TrdsObjectPtr = std::shared_ptr<TrdsObject>;
using FieldPtr = std::shared_ptr<Field>;

#define MEMBER_OFFSET(class, field)	(pointer_int)(&((class*)0)->field)
#define MEMBER_SIZEOF(class, field)	sizeof((((class*)0)->field))

#define CLASS_NAME(class)	virtual std::string GetClassName()const { return #class; }
#define OBJECT_NAME			public: virtual std::string GetObjName()const { return mName; } virtual std::string SetObjName(const std::string& name) { return mName = name; } private: std::string mName = "default";
#define TRDS_RELECT(class)  public: virtual MetaObjectPtr Meta(){ if(!metaobj_) { metaobj_.swap(Meta::GetInstance()->GetMetaObject(this, #class));}  return metaobj_; } CLASS_NAME(class)

#define REGISTER_FIELD(class, name)		RegisterHelper class_##name##_Register(#class, #name, MEMBER_OFFSET(class, name), MEMBER_SIZEOF(class, name));
#define REGISTER_INVOKE(class, name)	RegisterHelper class_##name##_function_Register(#class, MetaFunction(#name, &class::name));

#define REGISTER_MULTI_FIELD_1(class,	_1) REGISTER_FIELD(class, _1)
#define REGISTER_MULTI_FIELD_2(class,	_1, _2) REGISTER_MULTI_FIELD_1(class, _1) REGISTER_FIELD(class, _2)
#define REGISTER_MULTI_FIELD_3(class,	_1, _2, _3) REGISTER_MULTI_FIELD_2(class, _1, _2) REGISTER_FIELD(class, _3)
#define REGISTER_MULTI_FIELD_4(class,	_1, _2, _3, _4) REGISTER_MULTI_FIELD_3(class, _1, _2, _3) REGISTER_FIELD(class, _4) 
#define REGISTER_MULTI_FIELD_5(class,	_1, _2, _3, _4, _5) REGISTER_MULTI_FIELD_4(class, _1, _2, _3, _4)  REGISTER_FIELD(class, _5)
#define REGISTER_MULTI_FIELD_6(class,	_1, _2, _3, _4, _5, _6) REGISTER_MULTI_FIELD_5(class, _1, _2, _3, _4, _5) REGISTER_FIELD(class, _6)
#define REGISTER_MULTI_FIELD_7(class,	_1, _2, _3, _4, _5, _6, _7) REGISTER_MULTI_FIELD_6(class, _1, _2, _3, _4, _5, _6) REGISTER_FIELD(class, _7)
#define REGISTER_MULTI_FIELD_8(class,	_1, _2, _3, _4, _5, _6, _7, _8) REGISTER_MULTI_FIELD_7(class, _1, _2, _3, _4, _5, _6, _7) REGISTER_FIELD(class, _8) 
#define REGISTER_MULTI_FIELD_9(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9) REGISTER_MULTI_FIELD_8(class, _1, _2, _3, _4, _5, _6, _7, _8)  REGISTER_FIELD(class, _9) 
#define REGISTER_MULTI_FIELD_10(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) REGISTER_MULTI_FIELD_9(class, _1, _2, _3, _4, _5, _6, _7, _8, _9)  REGISTER_FIELD(class, _10) 
#define REGISTER_MULTI_FIELD_11(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) REGISTER_MULTI_FIELD_10(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10)  REGISTER_FIELD(class, _11) 
#define REGISTER_MULTI_FIELD_12(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) REGISTER_MULTI_FIELD_11(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11)  REGISTER_FIELD(class, _12) 
#define REGISTER_MULTI_FIELD_13(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) REGISTER_MULTI_FIELD_12(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12)  REGISTER_FIELD(class, _13) 
#define REGISTER_MULTI_FIELD_14(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) REGISTER_MULTI_FIELD_13(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13)  REGISTER_FIELD(class, _14) 
#define REGISTER_MULTI_FIELD_15(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) REGISTER_MULTI_FIELD_14(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14)  REGISTER_FIELD(class, _15) 
#define REGISTER_MULTI_FIELD_16(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) REGISTER_MULTI_FIELD_15(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)  REGISTER_FIELD(class, _16) 
#define REGISTER_MULTI_FIELD_17(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) REGISTER_MULTI_FIELD_16(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16)  REGISTER_FIELD(class, _17) 
#define REGISTER_MULTI_FIELD_18(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) REGISTER_MULTI_FIELD_17(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17)  REGISTER_FIELD(class, _18) 
#define REGISTER_MULTI_FIELD_19(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) REGISTER_MULTI_FIELD_18(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18)  REGISTER_FIELD(class, _19) 
#define REGISTER_MULTI_FIELD_20(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20) REGISTER_MULTI_FIELD_19(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19)  REGISTER_FIELD(class, _20) 


#define REGISTER_MULTI_FUNCTION_1(class,	_1) REGISTER_INVOKE(class, _1)
#define REGISTER_MULTI_FUNCTION_2(class,	_1, _2) REGISTER_MULTI_FUNCTION_1(class, _1) REGISTER_INVOKE(class, _2)
#define REGISTER_MULTI_FUNCTION_3(class,	_1, _2, _3) REGISTER_MULTI_FUNCTION_2(class, _1, _2) REGISTER_INVOKE(class, _3)
#define REGISTER_MULTI_FUNCTION_4(class,	_1, _2, _3, _4) REGISTER_MULTI_FUNCTION_3(class, _1, _2, _3) REGISTER_INVOKE(class, _4) 
#define REGISTER_MULTI_FUNCTION_5(class,	_1, _2, _3, _4, _5) REGISTER_MULTI_FUNCTION_4(class, _1, _2, _3, _4)  REGISTER_INVOKE(class, _5)
#define REGISTER_MULTI_FUNCTION_6(class,	_1, _2, _3, _4, _5, _6) REGISTER_MULTI_FUNCTION_5(class, _1, _2, _3, _4, _5) REGISTER_INVOKE(class, _6)
#define REGISTER_MULTI_FUNCTION_7(class,	_1, _2, _3, _4, _5, _6, _7) REGISTER_MULTI_FUNCTION_6(class, _1, _2, _3, _4, _5, _6) REGISTER_INVOKE(class, _7)
#define REGISTER_MULTI_FUNCTION_8(class,	_1, _2, _3, _4, _5, _6, _7, _8) REGISTER_MULTI_FUNCTION_7(class, _1, _2, _3, _4, _5, _6, _7) REGISTER_INVOKE(class, _8) 
#define REGISTER_MULTI_FUNCTION_9(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9) REGISTER_MULTI_FUNCTION_8(class, _1, _2, _3, _4, _5, _6, _7, _8)  REGISTER_INVOKE(class, _9) 
#define REGISTER_MULTI_FUNCTION_10(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) REGISTER_MULTI_FUNCTION_9(class, _1, _2, _3, _4, _5, _6, _7, _8, _9)  REGISTER_INVOKE(class, _10) 
#define REGISTER_MULTI_FUNCTION_11(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) REGISTER_MULTI_FUNCTION_10(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10)  REGISTER_INVOKE(class, _11) 
#define REGISTER_MULTI_FUNCTION_12(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) REGISTER_MULTI_FUNCTION_11(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11)  REGISTER_INVOKE(class, _12) 
#define REGISTER_MULTI_FUNCTION_13(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) REGISTER_MULTI_FUNCTION_12(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12)  REGISTER_INVOKE(class, _13) 
#define REGISTER_MULTI_FUNCTION_14(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) REGISTER_MULTI_FUNCTION_13(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13)  REGISTER_INVOKE(class, _14) 
#define REGISTER_MULTI_FUNCTION_15(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) REGISTER_MULTI_FUNCTION_14(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14)  REGISTER_INVOKE(class, _15) 
#define REGISTER_MULTI_FUNCTION_16(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) REGISTER_MULTI_FUNCTION_15(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)  REGISTER_INVOKE(class, _16) 
#define REGISTER_MULTI_FUNCTION_17(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) REGISTER_MULTI_FUNCTION_16(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16)  REGISTER_INVOKE(class, _17) 
#define REGISTER_MULTI_FUNCTION_18(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) REGISTER_MULTI_FUNCTION_17(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17)  REGISTER_INVOKE(class, _18) 
#define REGISTER_MULTI_FUNCTION_19(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) REGISTER_MULTI_FUNCTION_18(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18)  REGISTER_INVOKE(class, _19) 
#define REGISTER_MULTI_FUNCTION_20(class,	_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20) REGISTER_MULTI_FUNCTION_19(class, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19)  REGISTER_INVOKE(class, _20) 


#define REFLECT_COUNT_OF_N_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
#define REFLECT_COUNT_OF_N(...) REFLECT_COUNT_OF_N_IMPL(##__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

#define REFLECT_EXPAND_2(x) x
#define REFLECT_EXPAND(x) REFLECT_EXPAND_2(x)

#define REFLECT_CONTACT_2(x, y) x##y
#define REFLECT_CONTACT(x, y) REFLECT_CONTACT_2(x, y)

#define REGISTER_FIELDS(class, ...) REFLECT_EXPAND(REFLECT_CONTACT(REGISTER_MULTI_FIELD_, REFLECT_COUNT_OF_N(__VA_ARGS__)))(class, __VA_ARGS__)
#define REGISTER_INVOKES(class, ...) REFLECT_EXPAND(REFLECT_CONTACT(REGISTER_MULTI_FUNCTION_, REFLECT_COUNT_OF_N(__VA_ARGS__)))(class, __VA_ARGS__)

class REFLECT_EXPORT Meta
{
public:
	static Meta* GetInstance();
	MetaObjectPtr GetMetaObject(const TrdsObject* _o, const std::string& _class);
	TrdsObjectPtr NewInstance(const std::string& _class);

	void RegisterNew(const std::string& _class, const MetaFunction& newc);
	void RegisterInvoke(const std::string& _class, const MetaFunction& newc);
	void RegisterField(const std::string& _class, FieldPtr _filed);
protected:

protected:
	Meta();
	Meta(const Meta&) = delete;
	Meta(Meta&&) = delete;
	Meta& operator=(const Meta&) = delete;
	Meta& operator=(Meta&&) = delete;

private:
	std::shared_ptr<MetaImpl> meta_;
};

class REFLECT_EXPORT TrdsObject
{
	OBJECT_NAME
	TRDS_RELECT(TrdsObject)
public:
	template<typename SubType>
	SubType* Dynamic_cast()
	{
		return dynamic_cast<SubType*>(this);
	}
protected:
	MetaObjectPtr metaobj_;
};

class REFLECT_EXPORT MetaObject
{
	friend MetaImpl;
public:
	MetaObject(TrdsObject* _o, const Invokes& invokes, const Fields& fields, const News& news);
	FieldPtr GetField(int _d)const;
	FieldPtr GetField(const std::string& _d)const;
	MetaFunction GetMethod(const std::string& _d)const;
	MetaFunction GetMethod(int _d)const;
	int GetMethodCount()const;
	int GetFieldCount()const;

protected:
	std::shared_ptr<MetaObjectImpl> meta_;
};

class REFLECT_EXPORT Field
{
public:
	std::string FieldName()const;
	int FieldSize()const;
	int Offset()const;
	std::string ClassName()const;
	TrdsObject* GetInstance()const;
	void SetValue(const Object& _val);
	Object GetValue()const;

	Field(int _offset, int size, const std::string& field);
	Field(TrdsObject* _o, int _offset, int size, const std::string& field);
protected:

private:
	std::shared_ptr<FieldImpl> meta_;
};

class REFLECT_EXPORT RegisterHelper
{
public:
	RegisterHelper(const std::string& clas_, const std::string& filed_, int offset_, int size_);
	RegisterHelper(const std::string& clas_, const MetaFunction& function, bool creator = false);
};

//end
}
}

#endif//REFLECT_H

2:Reflect.cpp

#include "reflect.h"
#include <algorithm>

namespace Trds {  namespace Reflect {

class REFLECT_EXPORT MetaImpl
{
public:
	MetaObjectPtr GetMetaObject(TrdsObject* _o, const std::string& _class)
	{
		if (reflect_new.find(_class) == reflect_new.end() && 
			reflect_call.find(_class) == reflect_call.end()&&
			reflect_field.find(_class) == reflect_field.end())
		{
			return nullptr;
		}
		
		return MetaObjectPtr(new MetaObject(_o, reflect_call, reflect_field, reflect_new));
	}

	TrdsObjectPtr NewInstance(const std::string& _class)
	{
		if (reflect_new.find(_class) == reflect_new.end())
		{
			return nullptr;
		}
		TrdsObject* trds = reflect_new[_class]().Value<TrdsObject*>();
		return TrdsObjectPtr(trds);
	}

	void RegisterNew(const std::string& _class, const MetaFunction& newc)
	{
		reflect_new[_class] = newc;
	}

	void RegisterInvoke(const std::string& _class, const MetaFunction& newc)
	{
		reflect_call[_class].push_back(newc);
	}

	void RegisterField(const std::string& _class, FieldPtr _filed)
	{
		reflect_field[_class].push_back(_filed);
	}

private:
	News		reflect_new;
	Invokes		reflect_call;
	Fields		reflect_field;
};

class REFLECT_EXPORT MetaObjectImpl
{
public:
	MetaObjectImpl(TrdsObject* _o, const Invokes& invokes, const Fields& fields, const News& news)
		:_o(_o),_invokes(invokes), _fields(fields),_news(news)
	{
		using FieldVector = std::vector<std::shared_ptr<Field>>;
		Fields::const_iterator iter = _fields.find(_o->GetClassName());
		if (iter != _fields.cend())
		{
			FieldVector& fields_ = const_cast<FieldVector&>(iter->second);
			std::sort(fields_.begin(), fields_.end(), [](const FieldPtr& f, const FieldPtr& s)
				{
					return f->Offset() < s->Offset();
				});
		}

		using MetaFunctionVector = std::vector<MetaFunction>;
		Invokes::const_iterator iter1 = _invokes.find(_o->GetClassName());
		if (iter1 != _invokes.cend())
		{
			MetaFunctionVector& metafunction_ = const_cast<MetaFunctionVector&>(iter1->second);
			std::sort(metafunction_.begin(), metafunction_.end(), [](const MetaFunction& f, const MetaFunction& s)
				{
					return f.GetLocalOffset() < s.GetLocalOffset();
				});
		}
	}

	int GetMethodCount()const
	{
		if (_MethodCount == -1)
		{
			auto name = _o->GetClassName();
			for (auto pair : _invokes)
			{
				if (pair.first == name)
				{
					_MethodCount = pair.second.size();
					break;
				}
			}
		}
		return _MethodCount;
	}

	MetaFunction GetMethod(const std::string& _d)const
	{
		auto name = _o->GetClassName();
		for (auto pair : _invokes)
		{
			if (pair.first != name)
			{
				continue;
			}

			for (auto ptr : pair.second)
			{
				if (ptr.GetName() == _d)
				{
					MetaFunction fun = ptr;
					fun.setTrdsObject(_o);
					return fun;
				}
			}
			break;
		}

		return MetaFunction();
	}

	MetaFunction GetMethod(int _d)const
	{
		auto& vect = _invokes.find(_o->GetClassName());
		if (_d >= vect->second.size())
		{
			return MetaFunction();
		}
		return vect->second[_d];
	}

	int GetFieldCount()const
	{
		if (_FieldCount == -1)
		{
			auto name = _o->GetClassName();
			for (auto pair : _fields)
			{
				if (pair.first == name)
				{
					_FieldCount = pair.second.size();
					break;
				}
			}
		}
		return _FieldCount;
	}

	FieldPtr GetField(int _d)const
	{
		auto& vect = _fields.find(_o->GetClassName());
		if (_d >= vect->second.size())
		{
			return 0;
		}
		return vect->second[_d];
	}

	FieldPtr GetField(const std::string& _d)const
	{
		auto name = _o->GetClassName();
		for (auto pair : _fields)
		{
			if (pair.first != name)
			{
				continue;
			}

			for (auto ptr : pair.second)
			{
				if (_d == ptr->FieldName())
				{
					return FieldPtr(new Field(_o, ptr->Offset(), ptr->FieldSize(), ptr->FieldName()));
				}
			}
			break;
		}

		return 0;
	}

private:
	TrdsObject*			_o{ nullptr };
	const Invokes&		_invokes;
	const Fields&		_fields;
	const News&	_news;
	mutable int			_FieldCount = -1;
	mutable int			_MethodCount = -1;
};

class FieldImpl
{
public:
	FieldImpl(int offset_, int size_, const std::string& field_, TrdsObject* o_)
		:offset_(offset_), size_(size_), field_(field_), o_(o_)
	{

	}
	FieldImpl(int offset_, int size_, const std::string& field_)
		:offset_(offset_), size_(size_), field_(field_), o_(0)
	{

	}
	int offset_;
	int size_;
	const std::string field_;
	const TrdsObject* o_;
};

Meta* Meta::GetInstance()
{
	static Meta _meta;
	return &_meta;
}

MetaObjectPtr Meta::GetMetaObject(const TrdsObject* _o, const std::string& _class)
{
	return meta_->GetMetaObject(const_cast<TrdsObject*>(_o), _class);
}

TrdsObjectPtr Meta::NewInstance(const std::string& _class)
{
	return meta_->NewInstance(_class);
}

void Meta::RegisterNew(const std::string& _class, const MetaFunction& newc)
{
	meta_->RegisterNew(_class, newc);
}

void Meta::RegisterInvoke(const std::string& _class, const MetaFunction& newc)
{
	meta_->RegisterInvoke(_class, newc);
}

void Meta::RegisterField(const std::string& _class, FieldPtr _filed)
{
	meta_->RegisterField(_class, _filed);
}

Meta::Meta()
{
	meta_.reset(new MetaImpl());
}

FieldPtr MetaObject::GetField(int _d)const
{
	return meta_->GetField(_d);
}

FieldPtr MetaObject::GetField(const std::string& _d) const
{
	return meta_->GetField(_d);
}

MetaFunction MetaObject::GetMethod(const std::string& _d) const
{
	return meta_->GetMethod(_d);
}

MetaFunction MetaObject::GetMethod(int _d) const
{
	return meta_->GetMethod(_d);
}

int MetaObject::GetMethodCount() const
{
	return meta_->GetMethodCount();
}

int MetaObject::GetFieldCount() const
{
	return meta_->GetFieldCount();
}

MetaObject::MetaObject(TrdsObject* _o, const Invokes& invokes, const Fields& fields, const News& news)
{
	meta_.reset(new MetaObjectImpl(_o, invokes, fields, news));

}

std::string Field::FieldName() const
{
	return meta_->field_;
}

int Field::FieldSize() const
{
	return meta_->size_;
}

int Field::Offset() const
{
	return meta_->offset_;
}

std::string Field::ClassName() const
{
	return meta_->o_->GetClassName();
}

TrdsObject* Field::GetInstance() const
{
	return const_cast<TrdsObject*>(meta_->o_);
}

void Field::SetValue(const Object& _val)
{
	if (!_val)
	{
		return;
	}
	char* ptr = const_cast<Object&>(_val).GetCharPtr();
	char* field = (char*)(meta_->o_) + meta_->offset_;
	memcpy(field, ptr, meta_->size_);
}

Object Field::GetValue() const
{
	char* ptr = (char*)(meta_->o_) + meta_->offset_;

	return Object(ptr, false);
}

Field::Field(TrdsObject* _o, int _offset, int size, const std::string& field)
{
	meta_.reset(new FieldImpl(_offset, size, field, _o));
}

Field::Field(int _offset, int size, const std::string& field)
{
	meta_.reset(new FieldImpl(_offset, size, field));
}

RegisterHelper::RegisterHelper(const std::string& clas, const std::string& filed_, int offset_, int size_)
{
	Meta::GetInstance()->RegisterField(clas, FieldPtr(new Field(offset_, size_, filed_)));
}

RegisterHelper::RegisterHelper(const std::string& clas_, const MetaFunction& function, bool creator)
{
	if (creator)
	{
		Meta::GetInstance()->RegisterNew(clas_, function);
	}
	else
	{
		Meta::GetInstance()->RegisterInvoke(clas_, function);
	}
}

//end
}
}

3:案例

#include <iostream>
#include "./cp_core/reflect.h"

using namespace Trds::Reflect;

struct CPData
{
	int a = 9999;
	void* pvoid = 0;
};

class CPTest : public Trds::Reflect::TrdsObject
{
	TRDS_RELECT(CPTest)
public:
	void show(const std::string& msg)
	{
		std::cout << "msg = " << msg << std::endl;
	}

public:
	int ma = 90;
	char ch = 'a';
	CPData data;
};
REGISTER_FIELDS(CPTest, ma, ch, data) // 需要注册多少个,你就加多少个属性,就这么简单
REGISTER_INVOKES(CPTest, show)		  // 需要注册多少个,你就加多少个函数,就这么简单

int main(int argc, char** argv)
{
	CPTest test;
	test.SetObjName("test");

	auto name = test.GetObjName();

	MetaObjectPtr meta = test.Meta();
	meta->GetMethod(0)(std::string("123456789"));
	meta->GetField("ma")->SetValue(123456789);
	auto data = meta->GetField("data")->GetValue().Value<CPData>();
	data.pvoid = &test;
	meta->GetField("data")->SetValue(data);

	auto count_of_field = meta->GetFieldCount();
	auto count_of_method = meta->GetMethodCount();



	return 0;
}

4:不足之处:目前的需要注册的属性的权限需要为public。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Visual C 技术内幕第四版.pdf》 是一本关于Visual C语言的技术指南。该书深入介绍了Visual C编程语言的内部结构和工作原理,适合有一定编程基础的读者学习和参考。 本书主要分为七个部分,内容包括Visual C工具和环境、语言基础、标准库、内存管理、多线程编程、Windows GUI编程和高级特性。通过阅读本书,读者可以全面了解Visual C编程语言的各个方面,并学会如何使用Visual C构建高效、稳定的应用程序。 其中,本书详细介绍了Visual C编译器的工作原理和高级优化技术,帮助读者深入理解编译器是如何将源代码转化为可执行文件的。此外,本书还介绍了Visual C的标准库,包括常用的数据结构和算法,以及如何使用这些库来编写高效的程序。 另外,本书还介绍了Visual C的内存管理机制,包括堆和栈的分配和释放,帮助读者避免内存泄漏和内存溢出等问题。同时,本书还讲解了多线程编程的核心概念和技术,使读者能够编写并发性能更好的程序。 此外,本书还详细介绍了Windows GUI编程的技巧和方法,包括使用MFC、WinAPI和.NET等框架来创建图形界面。最后,本书还介绍了一些高级特性,如异常处理、反射和元编程等,帮助读者提升自己的编程技能。 总的来说,《Visual C 技术内幕第四版.pdf》 是一本系统全面的Visual C编程技术指南,适合有一定编程基础的读者学习和参考。通过阅读本书,读者可以深入了解Visual C的内部结构和工作原理,并掌握使用Visual C编写高效、稳定应用程序的技巧和方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值