一直在研究如何巧妙地在c++語言層面上實現反射功能,boost庫內有乙個magic_get的反射,但是它是基於編譯時的模板反射,給使用者的感覺來說,雖然是非侵入式的,但是使用上不夠靈活,下面直接上**,看看執行時的反射是怎麼實現的。
#include #include #include template struct id{};
std::mapid_classname_map;
class register_type_tool
}};//註冊基本資料型別,也可以註冊自定義的結構體型別
#define register_type(type, index, size) \
register_type_tool reg_tool##index(#type, index);\
int type_to_id(id) \
std::size_t type_size(id) \
register_type(unsigned short , 1, sizeof(unsigned short))
register_type(unsigned int , 2, sizeof(unsigned int))
register_type(unsigned long long , 3, sizeof(unsigned long long))
register_type(signed char , 4, sizeof(signed char))
register_type(short , 5, sizeof(short))
register_type(int , 6, sizeof(int))
register_type(long long , 7, sizeof(long long ))
register_type(unsigned char , 8, sizeof(unsigned char))
register_type(char , 9, sizeof(char))
register_type(wchar_t , 10, sizeof(wchar_t))
register_type(long , 11, sizeof(long))
register_type(unsigned long , 12, sizeof(unsigned long))
register_type(void* , 13, sizeof(void*))
register_type(const void* , 14, sizeof(const void*))
register_type(char16_t , 15, sizeof(char16_t))
register_type(char32_t , 16, sizeof(char32_t ))
register_type(float , 17, sizeof(float))
register_type(double , 18, sizeof(double))
register_type(long double , 19, sizeof(long double))
register_type(char * , 20, sizeof(char *))
std::mapid_size_map;
std::size_t id_to_size(int id)else
}//用於執行時動態反射結構體欄位資訊的工具類
template class init );
type_ids->push_back(type_id);
if(id_size_map.count(type_id) == 0)
}return type{};
}template static void init(type)
};template std::vector*init::type_ids = new std::vector;
template bool init::is_init = false;
#define init(class) (init{})
#define init_type(class) init::init(class{})
template int get_fields_count()
template res get_field_value_by_idx(type &type, int idx)
int offset = 0;
for (int i = 0; i < idx; ++i)
}return *((res*)((size_t)&type + (size_t)offset));
}template std::string get_field_type_by_idx(int idx)
template void set_field_value_by_idx(type &type, int idx, valtype val)
int offset = 0;
for (int i = 0; i < idx; ++i)
}*((valtype*)((size_t)&type + (size_t)offset)) = val;
}#define getattroffset(classtype, attr) (size_t)(&((classtype*)0x000)->attr)
#pragma pack(1) //讓結構體不進行記憶體對齊
class data
data(short a, short b, char c, double d) : a(a), b(b), c(c), d(d) {}
private:
short a = init(data);
short b = init(data);
char c = init(data);
double d = init(data);
};#pragma pack()
int main()
return 0;
}
通過上面**的演示,我們完美的解決了執行時對結構體欄位進行反射。 C執行時庫
1.概論 執行時庫是 程式在執行時所需要的庫檔案,通常執行時庫是以 lib或 dll形式提供的。c執行時庫誕生於 20世紀 70年代,當時的程式世界還很單純,應用程式都是單執行緒的,多工或多執行緒機制在此時還屬於新觀念。所以這個 j時期的 c執行時庫都是單執行緒的。隨著 作業系統 多執行緒技術的發展...
C執行時庫
visual studio文件的新主頁是docs.microsoft.com上的visual studio 2017文件。可以在crt library features中找到該主題的最新版本。本主題討論構成c執行時庫的各種.lib檔案及其關聯的編譯器選項和預處理程式指令。c執行時庫 crt c執行時...
反射獲取執行時類的結構
屬性 1.getfields 獲取當前執行時類及其父類中宣告為public訪問許可權的屬性 2.getdeclaredfields 獲取當前執行時類中宣告的所有屬性。不包含父類中宣告的屬性 4.getmodifiers 許可權修飾符 5.gettype 資料型別 6.getname 變數名 獲取執行...