【问题标题】:DWORD variable with low/high word and low/high byte具有低/高字和低/高字节的 DWORD 变量
【发布时间】:2011-05-13 08:48:19
【问题描述】:

我们如何在 C 中读取和制作具有低位和高位字以及低位和高位字节的 DWORD 变量?

【问题讨论】:

    标签: c winapi types dword


    【解决方案1】:
    #include <stdint.h>
    #include <stdio.h>
    
    typedef union _little_endian{
        struct _word{
            union _msw{
                struct _msw_byte{
                    uint8_t MSB;
                    uint8_t LSB;
                } __attribute__((__packed__)) MSW_BYTE;
                uint16_t WORD;
            } MSW;
            union _lsw{
                struct _lsw_byte{
                    uint8_t MSB;
                    uint8_t LSB;
                } __attribute__((__packed__)) LSW_BYTE;
                uint16_t WORD;
            } LSW;
        } __attribute__((__packed__)) WORD;
        uint32_t DWORD;
    } DWORD;
    
    int main(int argc, char *argv[]){
        DWORD test1;
        test1.WORD.MSW.MSW_BYTE.MSB = 1;
        test1.WORD.MSW.MSW_BYTE.LSB = 2;
        test1.WORD.LSW.LSW_BYTE.MSB = 3;
        test1.WORD.LSW.LSW_BYTE.LSB = 4;
        printf("test1: hex=%x uint=%u\n", test1.DWORD, test1.DWORD);
        
        DWORD test2;
        test2.DWORD = 0x08080404;
        printf("test2: hex=%x uint=%u\n", test2.DWORD, test2.DWORD);
        printf("test2.WORD.MSW.MSW_BYTE.MSB: uint=%u\n", test2.WORD.MSW.MSW_BYTE.MSB);
        printf("test2.WORD.MSW.MSW_BYTE.LSB: uint=%u\n", test2.WORD.MSW.MSW_BYTE.LSB);
        printf("test2.WORD.LSW.LSW_BYTE.MSB: uint=%u\n", test2.WORD.LSW.LSW_BYTE.MSB);
        printf("test2.WORD.LSW.LSW_BYTE.LSB: uint=%u\n", test2.WORD.LSW.LSW_BYTE.LSB);
        
        return 0;
    }
    

    我更喜欢使用结构和联合的组合。

    输出:

    test1: hex=4030201 uint=67305985
    test2: hex=8080404 uint=134743044
    test2.WORD.MSW.MSW_BYTE.MSB: uint=4
    test2.WORD.MSW.MSW_BYTE.LSB: uint=4
    test2.WORD.LSW.LSW_BYTE.MSB: uint=8
    test2.WORD.LSW.LSW_BYTE.LSB: uint=8
    

    【讨论】:

    • MS = 最重要,LS = 最不重要。谢谢。 :)
    【解决方案2】:

    WinAPI 为这些类型的操作提供了宏,例如:

    【讨论】:

    • 另外你有HIBYTELOBYTE分别
    【解决方案3】:

    在 Win32 中,DWORD 是一个 32 位无符号整数。在其他情况下,它可能意味着其他东西。

    假设 Win32 定义(和其他 Win32 类型定义):

    BYTE lsb = 0x11 :
    BYTE next_lsb = 0x22 :
    BYTE next_msb = 0x33 :
    BYTE msb = 0x44 :
    
    DWORD dword_from_bytes = (msb << 24) | (next_msb << 16) | (next_lsb << 8) | lsb ;
    

    dword_from_bytes 的值为 0x44332211

    同样:

    WORD lsw = 0x1111 :
    WORD msw = 0x2222 :
    
    DWORD dword_from_words = (msw << 16) | lsw ;
    

    dword_from_words 的值为 0x22221111

    例如从dword_from_bytes 中提取第三个字节:

    next_msb = (dword_from_bytes >> 16) & 0xff ;
    

    虽然考虑到next_msb的类型,在这种情况下&amp; 0xff并不是绝对必要的,但是如果接收器的类型大于8位,它将屏蔽掉msb位。

    【讨论】:

    • 现在开始有意义了。但是&lt;&lt;&gt;&gt;| 究竟是什么意思?谢谢!
    • 最好使用专用的宏,如HIWORDLOWORDMAKELONG等。因为不同的处理器使用不同的字节顺序(小/大端等)跨度>
    • 好吧,没关系。我已阅读有关按位运算符的文档,并且现在了解它的工作原理!
    • @valdo:虽然我同意应该使用 API 定义的宏,但字节顺序不是问题;例如(msw &lt;&lt; 16) 将始终在高位单词中放置一个值,而不管字节顺序如何。还有其他宏用于在不同字节序的机器之间交换数据。他们所做的是封装 API 定义字长的知识,以确保一致性并避免错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多