2010-06-09 113 views
0

我有一个C指针类型结构法称为uchar4它看起来像转换的C指针类型

{ 
    uchar x; 
    uchar y; 
    uchar z; 
    uchar w; 
} 

我也有传过来UINT8 *数据。我想创建一个UCHAR *在UINT8指向的数据*所以我试着这样做:

uint8 *data_in; 
uchar4 *temp = (uchar4*)data_in; 

然而,前8个字节似乎总是会出错。有没有另外一种方法呢?

编辑:

输入数据= 32 43 F6 A8 88 5A 30 8D 31 31 98 A2 E0 37 07 34

输出数据= 32 88 31 E0 37 07 34 8D 31 31 98 A2 E0 37 07 34

前半部分是总是这些看似随机值

+0

它与data_in中的内容不匹配,但始终是相同的错误值。 – giroy 2010-06-09 02:58:13

+0

你能告诉我们你用来打印输出的代码吗?它只是一个4字节的结构,你从哪里读取其他4个字节? – egrunin 2010-06-09 04:10:06

回答

1

看哪,不起眼的工会:

#include <stdio.h> 

typedef struct { 
    unsigned char x, y, z, w; 
} xyzw; 

typedef union { 
    xyzw x; 
    unsigned int i; 
} ixyzw; 


unsigned int xyzw_to_i(ixyzw *p) 
{ 
    return p->i; 
} 

int main() 
{ 
    xyzw x = {1, 2, 3, 4}; 

    printf("sizeof unsigned char %d\n", sizeof(unsigned char)); 
    printf("sizeof unsigned int %d\n", sizeof(unsigned int)); 
    printf("sizeof xyzw   %d\n", sizeof(xyzw)); 
    printf("sizeof ixyzw   %d\n", sizeof(ixyzw)); 

    printf("xyzw = { %d, %d, %d, %d }\n", x.x, x.y, x.z, x.w); 
    printf("i = 0x%08x\n", xyzw_to_i((ixyzw *) &x)); 
    return 0; 
} 

这在我的机器上发生的产生:

sizeof unsigned char 1 
sizeof unsigned int 4 
sizeof xyzw   4 
sizeof ixyzw   4 
xyzw = { 1, 2, 3, 4 } 
i = 0x04030201 

但跨编译或机器这种行为根本不能指望。

+0

它可能是谦虚,但它知道它在做什么!谢谢!也许有一天我可以在没有工会的情况下工作。 – giroy 2010-06-09 03:27:25

+1

这不是未定义的行为?(我知道它是用于C++,不知道关于标准c) – 2010-06-09 03:30:11

+1

“未定义”是的,编译器可以自由地对数据进行排序和对齐,但是它喜欢。在这种情况下,“未定义”的意思是“完全不可移植”,不是“不做任何事情”,也不是“可能对给定的机器/编译器给出不一致的解释”。大多数操作系统都依赖于内核某处的这种“未定义”行为,特别是在处理奇数器件寄存器时。 – msw 2010-06-09 03:39:36

1
  1. 如果sizeof(uint8) != sizeof(uchar4),那么所有的赌注都关闭。
  2. 您是否意识到整数的字节不一定按您期望的顺序保存(在内存中)?

编辑补充 此示例打印c3 d2 e1 f0。这是否回答你的问题?

#include <stdio.h> 
typedef unsigned char uchar; 
typedef struct { 
    uchar a; 
    uchar b; 
    uchar c; 
    uchar d; 
} uchar4; 

int main() { 
    int theInt = 0xf0e1d2c3; 
    uchar4 *p = (uchar4 *) &theInt; 
    printf("%x %x %x %x\n", p->a, p->b, p->c, p->d); 
    return 0; 
} 

另外:如果sizeof(uint8) == 8,其中的DWORD的你想你的结构是映射?

+0

我已经解释了(1)并且知道了(2)。没有明确地复制数据,有没有更好的方式来做类似的事情?我知道我是挑选,但速度对我的系统非常重要 – giroy 2010-06-09 02:54:20

+0

指针别名对速度的帮助不大。 – dreamlax 2010-06-09 03:15:24

+0

我认为它会,如果它更换一个冗长的memcpy或手动复制通过循环 – giroy 2010-06-09 03:19:01

0

您的编译器将对齐四个字节边界上的结构成员。这就是为什么你只能得到每第四个字节(其余的被认为是结构中的填充空间)。为了避免这种行为,你需要声明结构包装。它是如何完成的取决于编译器(而不是每个编译器都支持它)。有了GCC,你可以这样做:

struct uchar4 { 
    uchar a; 
    uchar b; 
    uchar c; 
    uchar d; 
} __attribute__((__packed__));