用于将任意结构从主机转换为网络字节顺序的C函数?

时间:2017-06-19 10:09:53

标签: c endianness

我创建了一个函数my_hton(),用于将主机字节顺序的数据转换为网络字节顺序。它转换任意结构的对象。如果它是正确的,为什么C有像htons()htonl()这样的函数,它们只分别转换2和4个字节,而不是对所有数据类型都有一个函数,或者我错过了什么?

void my_hton(char *buffer, char *p, size_t i){
    if( is_little_endian() ){
        while(i > 0){
            *buffer = p[i-1];
            buffer++;
            i--;
        }
    }
}

struct demo{
    int a;
    char b;
    char str[100];
    float f;
    double d;
    int *ptr;
};

int main() {
    char buffer[10000] = "";
    struct demo object;

    /*
    * object initialization
    */

    my_hton(buffer, (char*) &object, sizeof(object));

    return 0;
}

2 个答案:

答案 0 :(得分:1)

您在代码中所做的是按字节顺序翻转整个结构,这会导致您的个人成员出现乱码。

更好的问题是为什么要转换整个结构的字节序?

更改单个整数类型字段的字节顺序是有意义的,但这需要有关字段的信息,因此您不能拥有通用函数。

另一方面,如果您的结构具有相等填充的固定大小元素,那么您可以编写一个通用函数,它可以转换每个字段的字节序。但是我相信为网络制作的大多数结构都是打包的,这种情况非常罕见。

答案 1 :(得分:0)

一般情况下你不能这样做(因为结构字段除了标量的字节序外还有padding and alignment),特别是因为C没有type introspectionreflection设施。此外,还不清楚指针或联合应该做什么或一般中的flexible array members

详细了解serialization

您可以考虑自定义某些C编译器(例如,使用MELT扩展GCC或您自己的插件)来帮助您完成该序列化任务。我不认为这是值得的。

但是,一些框架正在添加此类设施。在GTK Gobject introspection中查找示例。另外看看C代码生成器 RPCGENSWIG。考虑二进制格式,如XDRSMILEASN1

在许多情况下,它更方便(即使稍慢,但瓶颈通常是网络或磁盘,而不是CPU,因此在大多数情况下你甚至都不会注意到)使用某些文本格式,如{ {3}},JSON,XML,....因为YAML非常常见且更容易调试。您会发现许多库可以帮助您使用这些格式。