구조체 패딩 문의
글쓴이: munhoney / 작성시간: 수, 2009/11/18 - 9:04오후
안녕하세요
구조체 패딩관련하여 몇가지 의문사항이 있어서 문의드립니다.
시험 목적은 윈도우 VC++에서 사용한 구조체를 Linux로 네트워크를 통한 전달시 문제가 발생하여
같은 구조체 패딩 구조를 갖고자 합니다.
예를 들면,
#include <stdio.h> typedef struct data1 { int a; double b; int c; } data1; int main() { printf("size : %d \n", sizeof(data1)); return 0; }
이와 같은 경우
VC++을 통해 컴파일하면,
size : 24
와 같이 나오고
Linux에서 하면
size : 16
이 나오지요.
물론 X86계열에서 테스트한 것입니다.
문제는 윈도우 시스템에서 VC++로 한 pack 구조를 그대로 리눅스에서 사용하고 싶다는 것입니다.
이를 위해 gcc 4.2(?) 버전을 사용하고 있는데,
컴파일 옵션중에 -fpack-struct=8로 하면 될 것 같은데 문제는 4까지만 되더군요. 원래 8을 안되는 건가요?
(#pragma pack(8)도 해보았으나 마찬가지네요.)
혹, 리눅스 시스템에서 size : 24로 나올 수 있는지요. 구조체 항목마다 __attribute__(aligned(8)) 로 사용하면 되겠지만,
실제 프로젝트에서는 구조체가 너무 많아서 이렇게 하기에는 역부족입니다.
좋은 방법있으시면 알려주세용~~~
Forums:
...
구조체를 바로 네트웍으로 보내는 것은 권장되지 않는 통신 방법입니다.
(사실 권장 수준이 아니라, 컴파일러나 실행 환경에 따라 언제대로 오류가 날 가능성이 있죠)
구조체의 alignment는 굉장히 시스템에 의존적이기 때문이죠.
그러므로 네트웍 상에서 구조체를 주고 받으려면 serialize/deserialize 과정을 필요로 합니다. 물론, byte-order도 조정해야 하고요. serialize/deserialize 방법은 검색해보시면 많이 나옵니다.
답변 감사합니다. 하지만,,
네 먼저 답변 감사합니다. 하지만, 현재 프로젝트가 임베디드 프로젝트인데 serialize/deserialize 과정은 C#,Java같은 곳에서만 가능한것 아닌지요.
그리고 한 쪽은 이미 고정이 되어서 받는 다른 한 쪽에서 이를 맞추어야 하는 이상한 꼴(?)이 되어서요.
다른 방법은 없을까요?
---------------------------------
http://blog.naver.com/munhoney
---------------------------------
...
serialize/deserialize는 C#, java 등에서는 언어 혹은 라이브러리에서 지원합니다만, c는 직접해야 한다는 점 빼고는 별로 차이가 없습니다. 예를들면 아래와 같이요...
//serialize
memcpy(&sebuf[0], &st.a, 4);
memcpy(&sebuf[4], &st.b, 1);
memcpy(&sebuf[5], &st.c, 4);
// send data
send(fd, sebuf, 9, ...)
// recv data
recv(fd, dsebuf, 9, ...)
//deserialize
memcpy(&st.a, &dsebuf[0], 4);
memcpy(&st.b, &dsebuf[4], 1);
memcpy(&st.c, &dsebuf[5], 4);
음...
그냥 변수로 padding 을 넣어버리면 되지 않을까 싶네요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
물론 그런방법도 있지만,..
그 방법은 가장 최후에 할려고 남겨두고 있습니다. ^^''
왜냐하면 한쪽이 이미 개발이 완성이 되었고, 바꿀 구조체가 어마어마하거덩요.
메뉴얼하게 바꾸는 것도 정말 시간이 많이 걸릴것 같구요..
다른 방법은 없을까요?
---------------------------------
http://blog.naver.com/munhoney
---------------------------------
음..
i386, x86_64 라면 -malign-double 을 주면 double 을 기준으로 align 이 이루어질겁니다.
(추가 : double 이 포함된 구조체에 한해서 그렇게 되네요..)
다만, 그렇게 되면 ABI 와 맞지 않게 되기 때문에..
같은 플랫폼에서 이 옵션을 쓰지 않은 appl 과의 호환성이라던가..
빌드 관련 문서가 따라다녀야 해서.. 유지보수가 귀찮아질 수도 있습니다.
(코드만 보고 작업할 경우 의도하지 않은 miss 가 발생할 수도 있구요)
가급적.. 애초에 padding 이 일어나지 않도록 설계를 하거나..
명시적으로 padding 을 넣어서 묵시적인 padding 이 일어나지 않게 하는게..
좀 더 낫지 않을까 생각되네요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
아 .. 그렇군요...!!! 감사합니다.
아. -malign-double이 있었군요... 감사합니다. ^^
확인해보니 잘 되네요.
그런데.. 혹시 특정 struct에서만 국한하여 할 수도 있을까요? 그러면 전체적인 부분은 ABI가 맞아서 다름 appl과 문제가 없을 것이고
특정 부분 (네트워크로 전달시키는 부분)만 이 옵션을 사용할 수 있을것 같은데요..
아무튼 궁금한 점은 해결 되었습니다. 너무 감사합니다.
---------------------------------
http://blog.naver.com/munhoney
---------------------------------
1
삭제
.
.
댓글 달기