라이브러리&Module/표준라이브러리

C로 만든 데이터를 출력하려면?(#struct)(do it! 점프 투 파이썬-ch02)

JackSmith 2023. 1. 19.

이번시간에는 C언어 코드와 Python코드를 모두 다뤄볼건데요!

 

C언어로 만든 바이너리(이진) 데이터를 파이썬으로 읽어들여

c언어에서 적어내려간 구조체 데이터가 뭔지 해석해내는 걸 배워보겠습니다!

7.5(실수), 15(정수), 'A'

위와 같이 세개의 값을 main.c에 넣어 보겠습니다.

#include <stdio.h>
typedef struct { 
    double v; 
    int t; 
    char c;
} save_type;

int main() {
    save_type s = {7.5f, 15, 'A'};
    FILE *f = fopen("output", "w");
    fwrite(&s, sizeof(save_type), 1, f);
    fclose(f);
    return 0;
}

그러기 위해서 일단 save_type이라는 구조체를 구축했습니다.

and then,

s라는 변수이름을 가진 save_type타입의 구조체를 생성하여,

위 세개의 값을 모두 넣어주었습니다.

 

그리고 output이라는 파일을 만들고, f라는 파일 포인터가 이를 참조하도록 밑밥을 깔고,

아래쪽에 void를 리턴하는 fwrite()메소드를 써주었습니다.

fwrite() 메소드는,

fwrite(const void *restrict ptr, size_t size, size_t n, FILE *restrict s)

위와 같이 포인터 인수 하나랑,

사이즈 인수 두개,

파인 참조 포인터 한개

를 파라미터로 받습니다.

  • 첫번째 파라미터(const void *restrict ptr) -> c코드 속 메모리에 있던 데이터들의 주소
  • 두번째 파라미터(size_t size) -> c코드 속 메모리의 크기(size)
  • 세번째 파라미터(size_t n) -> 1 
  • 네번째 파라미터(FILE *restrict s) -> 생성한 바이너리 파일, 즉 스토리지의 주소

 

이렇게 해주고, 컴파일 해주면,

위와 같이 같은 디렉토리 아래에 output이라는 파일이 만들어졌습니다.

이 파일은 txt파일이 아니기 때문에, 제대로 열리지 않습니다.

그래서 이 파일을 제대로 열어보기 위해 Python으로 코드를 짜줄 겁니다.

아래와 같이 struct 모듈의 unpack() 함수를 사용하면 C 구조체를 쉽게 읽을 수 있어요!
import struct
with open('output', 'rb') as f:
    chunk = f.read(16)
    result = struct.unpack('dicccc', chunk)
    print(result)

1.unpack() 함수의 첫번쨰 인수 'dicccc'는 double형 1개, int형 1개, char형 14개를 뜻한다.

기본에 main.c에서 save_type구조체는

double 1개, int 1개, char 1개이므로,

총 13(8+4+1)바이트면 되는데,

왜 16바이트를 할당해서 일부러 메모리 낭비를 하냐고 물어볼 수 있는데,

그냥 16바이트에 맞추도록 이 함수에 안에서 규칙상 정한 것 같다.

그래서 억지로 16바이트에 끼워 맟춰야 하는 것 같다.

 

 

※업데이트※

정정하겠습니다^^;;

unpack함수가 무조건 16바이트로 맞춘것만 받겠다는게 아니라!!

c언어 측에서 애초에 16바이트짜리 구조체를 만들어주었기 때문인데요!

구조체의 길이가 13바이트가 아닌 16바이트인 이유는!

c언어 구조체상의 고유한 규칙이 있어선데요!

가장 몸집이 큰 double형의 크기 8바이트의 배수로 구조체의 길이가 결정되기 때문입니다!

 

따라서 이 double형 타입을 갖고 있는 save_type이라는

구조체는 8,16,24..등으로 구조체 사이즈를 결정하는데,

8바이트 초과 16바이트 이하로 구조체 속 멤버들을 모두 넣을 수 있으므로,

이 구조체는 16바이트로 결정이 됩니다.

 

(그럼, 나머지는 어떻게 되는 거죠?

실제 데이터 13바이트를 제외한 나머지 3바이트는 널값으로 채워집니다.)

 

출처:

https://wikidocs.net/104663

 

004 C로 만든 데이터를 출력하려면? ― struct

struct는 C 언어로 만든 구조체 이진 데이터를 처리할 때 활용하는 모듈이다. C 구조체로 만들어진 파일을 읽거나 네트워크로 전달되는 C 구조체 이진 데이터를 파이썬에서 처리…

wikidocs.net

 

댓글