C에서 "포장된" 구조는 무엇입니까?
나는 마이크로칩 C30 컴파일러용으로 작성된 C 코드를 살펴보고 있으며 종종 다음과 같이 정의된 구조를 봅니다.
typedef struct __attribute__((__packed__))
{
IP_ADDR MyIPAddr; // IP address
IP_ADDR MyMask; // Subnet mask
IP_ADDR MyGateway; // Default Gateway
// etc...
} APP_CONFIG;
packed가 무슨 뜻입니까?
구조가 정의되면 컴파일러는 패딩(실제 데이터가 없는 공간)을 추가할 수 있으므로 구성원이 CPU에 더 쉽게 액세스할 수 있는 주소 경계에 속합니다.
예를 들어 32비트 CPU에서 32비트 멤버는 효율적으로 액세스(읽기 및 쓰기)하려면 4바이트의 배수 주소에서 시작해야 합니다.다음 구조 정의는 두 구성원 사이에 16비트 패딩을 추가하여 두 번째 구성원이 적절한 주소 경계에 속하도록 합니다.
struct S {
int16_t member1;
int32_t member2;
};
32비트 아키텍처에서 위의 구조를 기억하는 구조는 (~ = 패딩):
+---------+---------+
| m1 |~~~~| m2 |
+---------+---------+
구조물이 채워질 때 이러한 패딩은 삽입되지 않습니다.컴파일러는 정렬되지 않은 데이터 멤버를 추출하고 쓰기 위해 더 많은 코드(더 느리게 실행됨)를 생성해야 합니다.
동일한 구조가 패킹되면 메모리에 다음과 같이 나타납니다.
+---------+---------+
| m1 | m2 |~~~~
+---------+---------+
컴파일러가 구성원 간에 패딩을 추가하지 않도록 지시합니다.struct
.
예를 들어, 이 페이지를 참조하십시오.
예를 들어 구조물의 패딩과 패킹 구조물의 개념을 설명하겠습니다.
그리고 왜 포장이 필요한지 알아보겠습니다.
패딩:
struct eg_struct
{
unsigned char abc;
unsigned int xyz;
}
16비트 아키텍처에서 구조가 위와 같이 선언될 때, 변수는abc
주소가 할당될 것입니다.다음 주소가 변수에 할당되지 않았습니다.xyz
대신 하나의 추가 바이트가 추가되고 다음 주소가 변수에 할당됩니다.xyz
.
결국, 구조는 다음과 같습니다.
struct eg_struct
{
unsigned char abc;
unsigned char paddedbytes[1];
unsigned int xyz;
}
패딩을 사용하면 멤버 변수의 주소를 마이크로컨트롤러에서 쉽게 액세스할 수 있습니다.단점은 사진에 들어오는 불필요한 바이트입니다.
포장:
속성 "을 사용하여 동일한 구조가 선언된 경우packed
변수 뒤에 추가 바이트가 추가되지 않습니다.abc
.
포장이 필요한 한 가지 예를 들어 보겠습니다.
일부 구조물이 저장되는 EEPROM과 인터페이스된 마이크로컨트롤러를 생각해 보십시오.
EEPROM에 기록하는 기능을 다음과 같이 상상해 보십시오.
Write_EEPROM(EEPROM address, Ram address, Byte count);
패킹을 하지 않으면 추가 패딩된 바이트가 EEPROM의 공간을 차지하게 되어 아무 소용이 없습니다.
_attribute__((__packed__))
는 "더 빨리 만들기 위해 패딩을 삽입하지 않음"을 의미하며, "정렬을 유지하기 위해 정렬을 삽입하지 않음"을 의미할 수도 있습니다.
명시적으로 호출되지 않은 한 가지는 패킹이 일반적으로 사전 정의된 필드 구조와 일치하도록 수행된다는 것입니다.예를 들어 네트워크 인터페이스의 하위 계층에서는 네트워크 시스템 간에 일련의 바이트가 교환됩니다.데이터를 수신한 후에는 데이터를 쉽게 조작할 수 있도록 높은 수준의 구조로 매핑해야 합니다.이것은 구조가 바이트에 직접 매핑되도록 일반적으로 패딩이 필요하지 않은 경우입니다.
네트워크 데이터 교환에는 바이트 엔디언 문제도 포함됩니다(즉, 거의 모든 네트워크 데이터는 소스 및 대상 시스템의 엔디언과 관계없이 빅 엔디언 형식을 사용합니다).
또한 Cortex-M0 코어는 32비트가 아닌 주소의 32비트 데이터에 액세스할 수 없으므로 이러한 경우 네트워킹 코드를 작성하는 데 주의해야 합니다.
구조체 선언 중에 패킹을 사용하면 컴파일러는 동일한 구조체의 멤버에 패딩을 추가하지 않습니다.아래는 자체 설명이 가능한 코드 및 출력 예제입니다.
$ cat structure_packed.c
#include <stdio.h>
typedef struct __attribute__((__packed__))
{
char a;
int ai;
char ac;
}A;
struct B
{
char b;
int bi;
char bc;
};
int main()
{
A a;
struct B b;
int c;
printf("size of struct A: %lu, addr a: %p, addr ai: %p, addr ac: %p\n", sizeof(a), &(a.a), &(a.ai), &a.ac);
printf("size of struct B: %lu, addr b: %p, addr bi: %p, addr bc: %p\n", sizeof(b), &(b.b), &(b.bi), &b.bc);
printf("addr of c: %p\n", &c);
return 0;
}
컴파일
$ gcc structure_packed.c -o structure_packed
실행|출력
$ ./structure_packed size of struct A: 6, addr a: 0x7ffc6f177ed6, addr ai: 0x7ffc6f177ed7, addr ac: 0x7ffc6f177edb size of struct B: 12, addr b: 0x7ffc6f177edc, addr bi: 0x7ffc6f177ee0, addr bc: 0x7ffc6f177ee4 addr of c: 0x7ffc6f177ed0
언급URL : https://stackoverflow.com/questions/5473189/what-is-a-packed-structure-in-c
'sourcetip' 카테고리의 다른 글
Python ValueError: 값이 너무 많아 압축을 풀 수 없습니다. (0) | 2023.06.07 |
---|---|
vuex 스토어는 setTimeout 이후에만 사용할 수 있는 이유는 무엇입니까? (0) | 2023.06.07 |
Makefile:1: *** 구분 기호가 없습니다.이제 그만 (0) | 2023.06.07 |
python dict.update()가 개체를 반환하지 않는 이유는 무엇입니까? (0) | 2023.06.07 |
Python을 사용하여 스프레드시트에 매크로 삽입 (0) | 2023.06.07 |