2010-06-09 5 views
0

나는 또한 UINT8로 * 전달 된 데이터가 변환 C 포인터 유형은

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

처럼 보이는 structre 유형이라고 uchar4에 C 포인터를 가지고있다. 나는이 일을 * 내가 시도한 UINT8에서 데이터를 가리키는 UCHAR를 * 만들 싶습니다

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

그러나, 처음 8 바이트는 항상 잘못된 것 같다. 이 일을하는 또 다른 방법이 있습니까?

EDIT :

입력 데이터 = 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

+0

출력을 인쇄하는 데 사용하는 코드를 표시 할 수 있습니까? 그것은 단지 4 바이트짜리 구조체입니다, 당신은 다른 4 바이트를 어디서 읽었습니까? – egrunin

답변

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

+1

정의되지 않은 동작입니까?(나는 C++에 대해 알고 있지만, 표준 C에 대해서는 모른다) –

+1

컴파일러가 원하는대로 데이터를 정렬하고 정렬 할 수있는 "정의되지 않은"예. 이 문맥에서 "정의되지 않은"은 "전혀 이식성이 없다"는 의미이며, "아무것도하지 않거나"주어진 기계/컴파일러에 대해 일관성없는 해석을 할 가능성이 없다는 의미입니다. 대부분의 운영 체제는 특히 커널 안의 어딘가에있는 "정의되지 않은"동작에 의존합니다. 특히 이상한 장치 레지스터를 다루는 경우입니다. – msw

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) 알고 있습니다. 명시 적으로 데이터를 복사하지 않고도 이와 같은 작업을 수행하는 더 좋은 방법이 있습니까? 나는 니트 피킹 (knit-picking)을 알고 있지만 속도는 내 시스템에서 매우 중요합니다. – giroy

+0

포인터 앨리어싱은 속도를 크게 향상시키는 데 도움이되지 않습니다. – dreamlax

+0

나는 그것이 긴 memcpy 또는 수동 복사를 루프를 통해 – giroy

0

컴파일러가 구조체 멤버를 4 바이트 경계에 정렬합니다. 그래서 네 번째 바이트 만 가져옵니다 (나머지는 구조체의 패딩 공간으로 간주됩니다). 이 문제를 피하려면 구조체 으로 묶어 선언해야합니다. 이 작업은 컴파일러에 따라 다르며 모든 컴파일러가 지원하지는 않습니다. GCC를 사용하면 다음과 같이 처리 할 수 ​​있습니다.

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