正如其他人所指出的,反射并未内置于 C 或 C++ 语言中。这里有各种各样的想法
但是,反射在 C/C++ 中是可能的,带有第三方库和可执行文件或外部文件中的调试符号。
dwarfdump
可执行文件或多或少可以满足您的期望。有了 DWARF 信息,关于函数、变量、类型等的详细信息可用。以类似的方式,进程可以使用 libdwarfdump 功能来检查自身。
这是一个简单的手动示例:
typedef struct somestruct
{
int i;
int j;
} somestruct ;
int abc(int x, float y , struct somestruct z ){
char a;
int b ;
}
int main(int argc, char* argv[])
{
struct somestruct z;
abc(1,1.0f,z);
return 0;
}
以及 dwarfdump 的部分输出
< 1><0x00000055> DW_TAG_subprogram
DW_AT_external yes(1)
DW_AT_name "abc"
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000009
DW_AT_prototyped yes(1)
DW_AT_type <0x0000004e>
DW_AT_low_pc 0x004004ed
DW_AT_high_pc <offset-from-lowpc>18
DW_AT_frame_base len 0x0001: 9c: DW_OP_call_frame_cfa
DW_AT_GNU_all_call_sites yes(1)
DW_AT_sibling <0x000000ad>
< 2><0x00000076> DW_TAG_formal_parameter
DW_AT_name "x"
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000009
DW_AT_type <0x0000004e>
DW_AT_location len 0x0002: 916c: DW_OP_fbreg -20
< 2><0x00000082> DW_TAG_formal_parameter
DW_AT_name "y"
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000009
DW_AT_type <0x000000ad>
DW_AT_location len 0x0002: 9168: DW_OP_fbreg -24
< 2><0x0000008e> DW_TAG_formal_parameter
DW_AT_name "z"
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000009
DW_AT_type <0x0000002d>
DW_AT_location len 0x0002: 9160: DW_OP_fbreg -32
通过仔细研究,我们可以看到片段定义了函数“abc”,参数为 x、y 和 z。
参数 x 的类型是对带有键 0x4e 的类型表的间接引用。
查看输出中的其他地方,我们可以看到类型 0x4e 的定义。类型 0x2d 是与参数 z 相关联的 somestruct。
< 1><0x0000002d> DW_TAG_structure_type
DW_AT_name "somestruct"
DW_AT_byte_size 0x00000008
DW_AT_decl_file 0x00000001 /tmp/dwarf.c
DW_AT_decl_line 0x00000003
DW_AT_sibling <0x0000004e>
< 1><0x0000004e> DW_TAG_base_type
DW_AT_byte_size 0x00000004
DW_AT_encoding DW_ATE_signed
DW_AT_name "int"
ptrace、ELF、DWARF 和 /proc 文件系统的组合允许 gdb 读取进程的静态和动态信息。另一个进程可以使用类似的功能来创建反射功能。
我已使用此策略的变体来创建自定义调试器和内存泄漏检测器。但是,我从未见过将这种策略用于业务逻辑。