如何在C中转储任意结构?

new*_*erl 6 c struct dump

我不知道要走哪个方向,或许反射会有所帮助?

Jon*_*rth 9

如果您使用 Clang 8 或更新版本,您现在可以使用内置编译器函数__builtin_dump_struct来转储结构。它使用在编译时自然可用的信息来生成可漂亮打印结构的代码。

演示函数的示例代码:

转储结构.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;
}
Run Code Online (Sandbox Code Playgroud)

编译运行示例:

$ clang dumpstruct.c -o dumpstruct
$ ./dumpstruct 
struct dumpme {
int a : 1
int b : 2
struct nested n : struct nested {
    int aa : 12
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的不是 Clang >= 8,而是使用 GCC,则切换起来非常容易。只需安装 clang-8 或 clang-9 包并替换gccwith 的调用clang


Sim*_*nte 5

@Kerrek SB 的答案非常好,我只是发布了如何使用 void 指针在函数中使用它。

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;
}
Run Code Online (Sandbox Code Playgroud)


Ker*_* SB 3

这是一个十六进制转储,大约是您能得到的最通用的:

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]);
Run Code Online (Sandbox Code Playgroud)

请注意,此结果完全是实现定义的;想必会有大量的填充,并且您不会知道任何打印值的含义。(其中大多数可能只是指向空间其他部分的指针。)

正如 Etienne 所说,C 是一种静态类型语言,没有反射,因此您必须知道 的声明Foo才能解释 的内容x