我创建了一个函数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;
}
答案 0 :(得分:1)
您在代码中所做的是按字节顺序翻转整个结构,这会导致您的个人成员出现乱码。
更好的问题是为什么要转换整个结构的字节序?
更改单个整数类型字段的字节顺序是有意义的,但这需要有关字段的信息,因此您不能拥有通用函数。
另一方面,如果您的结构具有相等填充的固定大小元素,那么您可以编写一个通用函数,它可以转换每个字段的字节序。但是我相信为网络制作的大多数结构都是打包的,这种情况非常罕见。
答案 1 :(得分:0)
一般情况下你不能这样做(因为结构字段除了标量的字节序外还有padding and alignment),特别是因为C没有type introspection或reflection设施。此外,还不清楚指针或联合应该做什么或一般中的flexible array members。
详细了解serialization。
您可以考虑自定义某些C编译器(例如,使用MELT扩展GCC或您自己的插件)来帮助您完成该序列化任务。我不认为这是值得的。
但是,一些框架正在添加此类设施。在GTK Gobject introspection中查找示例。另外看看C代码生成器 RPCGEN或SWIG。考虑二进制格式,如XDR,SMILE,ASN1等
在许多情况下,它更方便(即使稍慢,但瓶颈通常是网络或磁盘,而不是CPU,因此在大多数情况下你甚至都不会注意到)使用某些文本格式,如{ {3}},JSON,XML,....因为YAML非常常见且更容易调试。您会发现许多库可以帮助您使用这些格式。