简体   繁体   English

如何在 C 中逐字节构造结构对象?

[英]How to construct struct objects byte by byte in C?

I'm working on creating a very basic version of file system using C.我正在使用 C 创建一个非常基本的文件系统版本。 As a part of it, I'm trying to read from disk and store the contents into a struct object .作为其中的一部分,我正在尝试从磁盘读取并将内容存储到struct object中。 According to the implementation, reading from disk is possible only byte by byte, of type unsigned char * .根据实现,只能逐字节读取磁盘,类型为unsigned char * Let's say size of the struct is N .假设结构的大小是N The goal is to read N bytes from disk and concatenate them to construct an object.目标是从磁盘读取N个字节并将它们连接起来以构造 object。

My approach:我的做法:

struct sample_struct {
    int a;
    char b;
};
    
void read_from_disk(int position, unsigned char* disk_pointer) {
    int struct_size = sizeof(sample_struct);
    sample_struct *s = new sample_struct();
    
    for(int i=0; i<struct_size;i++) {
        *s = *s | (disk_pointer[position + i] << (i*8)); // Error
    }
}

As seen in the simplified code above, I'm reading a byte, shifting it right by 8 bits and concatenating it, to form the full object.如上面的简化代码所示,我正在读取一个字节,将其右移 8 位并将其连接起来,形成完整的 object。 I'm getting the following error though: no operator "|" matches these operands -- operand types are: sample_struct | int我收到以下错误: no operator "|" matches these operands -- operand types are: sample_struct | int no operator "|" matches these operands -- operand types are: sample_struct | int

Am I completely off with my approach?我完全不同意我的方法吗? What would be the ideal way to do this?这样做的理想方法是什么?

Storing structs (and several other types) directly to a disk in raw format is doable but be aware that it also limits the use of the data to systems (computers, compilers, etc) that are 100% compatible with your specific system.将结构(和其他几种类型)以原始格式直接存储到磁盘是可行的,但请注意,它还会将数据的使用限制为与您的特定系统 100% 兼容的系统(计算机、编译器等)。

In general you enter an area where the C standard doesn't define what is going to happen.通常,您进入的区域 C 标准没有定义将要发生的事情。 To do what you want to do you will for instance violate the strict aliasing rule .例如,要执行您想做的事情,您将违反严格的别名规则

Anyway... to do this you need a unsigned char* pointing to the location of the struct and then fill the struct memory using that pointer.无论如何...要做到这一点,您需要一个指向结构位置的unsigned char* ,然后使用该指针填充结构 memory 。

Like:喜欢:

unsigned char * struct_alias = (unsigned char *)s;
for(int i=0; i<struct_size;i++) {
    struct_alias[i] = disk_pointer[position + i];
}

Just to repeat: This is non-standard C and consequently it's not portable code.重复一遍:这是非标准的 C,因此它不是可移植的代码。

There are several problems involved, eg struct size may differ on different systems, endianess may differ on different systems, some systems may have trap representation, etc...涉及到几个问题,例如不同系统上的结构大小可能不同,不同系统上的字节序可能不同,某些系统可能有陷阱表示,等等......

That said, it's very common for low level code to be system specific.也就是说,低级代码是系统特定的,这是很常见的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM