예전 글 복구 재게시.
. . .
MP3 디코딩 엔진 포팅을 하나 하다가.. 헤멘 부분 기록.
문제가 발생하는 상황은 다음과 같다.
뭐 대충 쓴 코드니까 상세는 보지 말고 원리만...
unsigned int r;
unsigned int *p = (unsigned int *)0x3000.... // 최초에 정의된 포인터, 4바이트 얼라인
unsigned char *pp; // 1바이트 얼라인..
pp = (unsigned char *)p; // 문제 없음..
pp++; // 바이트 증가, 현재 4바이트 얼라인에 맞지 않음.
r = yyy((void *)pp); // void 포인터로 전달.
. . .
unsigned int yyy(void *var)
{
return (unsigned int)(*var);
// 익셉션 뜨고 시스템 정지.
//4바이트 얼라인에 맞지 않기 때문.
}
// 에러 안 나는 함수 쉽게 풀어 써 봄.
unsigned int yyy(void *var)
{
unsigned int r;
unsigned char *temp; // 1바이트 얼라인 가능!!!!
temp = (unsigned char *)v;
r = *temp++ << 24; // 엔디안에 따라 바이트 순서는 서로 다름.
r |= *temp++ << 16; // 1바이트 얼라인 가능
r |= *temp++ << 8;
r |= *temp++ << 0;
return r;
}
// 퀴즈1. 한 줄로 줄여보자.
// 퀴즈2. 인라인 어셈으로 줄여보자.
void *형 포인터를 쓸 때는 항상 바이트 얼라인에 중요하자. 구조체 캐스팅 시에 이빨빠진 더미 공간도 항상 조심!!
gcc 에서 __attribute(..packed.. 어쩌구... 혹은 vc 계통에서 #pragma... 어쩌구 와는 달리. ads에서는 다음과 같이 한다.
typedef __packed struct
{
UINT32 fcc;
UINT32 cb;
UINT16 wFormatTag;
UINT16 nChannels;
UINT32 nSamplesPerSec;
UINT32 nAvgBytesPerSec;
UINT16 nBlockAlign;
UINT16 wBitsPerSample;
} WAVEFORM;
20세기 개발자 : 데이터가 칸칸이 나뉘어진 기차처럼 보임.
20세기말 개발자 : 데이터가 한 량에 4칸인 기차처럼 보임.
21세기 개발자 : 데이터가 보자기로 묶은 객체로 보임.
난 20세기말 개발자다 -_-;