我不知道往哪个方向走,也许像反射之类的东西会有所帮助?
@ Kerrek SB的答案确实非常好,我只是使用空指针发布了如何在函数中使用它。
int dump(void *myStruct, long size)
{
unsigned int i;
const unsigned char * const px = (unsigned char*)myStruct;
for (i = 0; i < size; ++i) {
if( i % (sizeof(int) * 8) == 0){
printf("\n%08X ", i);
}
else if( i % 4 == 0){
printf(" ");
}
printf("%02X", px[i]);
}
printf("\n\n");
return 0;
}
int main(int argc, char const *argv[])
{
OneStruct data1, data2;
dump(&data1, sizeof(OneStruct));
dump(&data2, sizeof(OneStruct));
return 0;
}
这里是一个十六进制转储,大约和您所能获得的差不多:
struct Foo x;
unsigned int i;
const unsigned char * const px = (unsigned char*)&x;
for (i = 0; i < sizeof(x); ++i) printf("%02X ", px[i]);
请注意,此操作的结果完全由实现定义;大概会有很多填充,您将不知道任何打印值的含义。 (它们中的大多数可能只是指向空间其他部分的指针。)
正如Etienne所说,C是一种静态类型的语言,没有反射,所以您必须知道Foo
的声明才能解释x
的内容。
一旦获得文件,您想如何处理?如果以后要读回,只需使用fread
和fwrite
,例如
struct foo * bar;
fwrite(bar,sizeof(*bar),1,stdout);
...
fread(bar,sizeof(*bar),1,stdin);
这将提供取决于您的编译器/平台的二进制输出,只要没有变化,您就可以了。从那里,您还可以将文件馈入十六进制读取器等,尽管您需要知道结构的布局才能对其进行任何有用的操作。
如果使用的是Clang 8或更高版本,则现在可以使用内置的编译器函数__builtin_dump_struct
转储结构。它使用编译时自然可用的信息来生成漂亮地打印结构的代码。
演示该功能的示例代码:
dumpstruct.c:
#include <stdio.h>
struct nested {
int aa;
};
struct dumpme {
int a;
int b;
struct nested n;
};
int main(void) {
struct nested n;
n.aa = 12;
struct dumpme d;
d.a = 1;
d.b = 2;
d.n = n;
__builtin_dump_struct(&d, &printf);
return 0;
}
示例编译运行:
$ clang dumpstruct.c -o dumpstruct
$ ./dumpstruct
struct dumpme {
int a : 1
int b : 2
struct nested n : struct nested {
int aa : 12
}
}
如果您不使用Clang> = 8,但您使用的是GCC,则切换起来非常容易。只需安装clang-8或clang-9软件包,然后将gcc
的调用替换为clang
。