C编程结构作为强制转换传递给char *?

时间:2010-03-01 23:31:21

标签: c

我遇到了一个小问题:

while (read(dp->fd, (char *) &dirbuf, sizeof(dirbuf)) == sizeof(dirbuf)) { ... }

其中dirbuf是:

struct direct dirbuf { 
    ino_t d_ino; char d_name[DIRSIZ]; 
};  

C如何知道将数据连续读入我们的结构?使用read()Like,我们的dirbuf的对齐非常适合作为字符数组?因为read接受一个void *作为它的第二个参数,将一个结构作为一个转换传递给char *对我来说没什么意义,它如何正确地迎合其他成员元素?

我不确定我是否正确地问这个问题,我希望有人可以解决我的精神错乱背后的问题并帮助我。

感谢。

3 个答案:

答案 0 :(得分:6)

歇斯底里的Raisens

将缓冲区转换为char *是一种经常看到的遗留代码模式。它经常被使用,以至于在它不再需要之后很久就会被输入。

有一点没有void类型,因此像read(2)这样的API会将缓冲区参数声明为char *,并且所有调用者都会将其数据转换为 char *

但是read(2)已经很长很长时间了void *。很长一段时间以来,必须在通话现场进行任何类型的演员表。

然而,旧代码仍然存在,人们仍在阅读它,然后它们使设计模式永久化。

它没有任何伤害。

关于连续数据,正在发生两件事之一。数据结构和类型被设计为在大多数或所有可能的机器上密集布局,或者首先使用类似的语句将数据写出来,因此填充字节无关紧要,除非要移动数据文件在不同的架构之间。

答案 1 :(得分:3)

它不会读取并正确对齐结构中的字段。它只需要结构的总大小(来自sizeof)和起始地址(来自&dirbuf)并读入该内存而不考虑结构声明。

假设文件中的任何内容已经正确对齐以适应结构。

(char *)演员阵容就是关闭编译器。 (void *)也会做得很好。或者根本没有强制转换,因为编译器会将指针类型转换为void *而不进行强制转换。

答案 2 :(得分:0)

这必须是对C语言的古老版本的点头,它没有void *类型而是使用char *代替。如果你使用的是非古老的编译器并且参数确实是void *,则不需要向char *投射任何东西(并且不需要向void *投射任何东西)

read(dp->fd, &dirbuf, sizeof(dirbuf)) 

C不知道,也不需要知道如何将数据读入您的特定结构。当您执行上述操作时,文件中的二进制数据将被盲目读入dirbuf对象占用的原始内存中。如果该二进制数据的布局是正确的(例如,如果文件是通过以相同的方式编写相同的结构来创建的),那么一切都将正确对齐,一切都将自动落入适当的位置。

请注意,除非您正在使用非常严格的规范所涵盖的内容,否则这种直接的二进制写/读技术只能在同一程序的单个会话中使用,或者可能在同一版本的不同会话之间使用在同一平台上的程序。一旦您开始在同一平台上处理不同平台和/或不同版本的代码,一旦数据的原始内存布局发生变化,事情就会轻易崩溃。