이번시간에는 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바이트는 널값으로 채워집니다.)
출처:
004 C로 만든 데이터를 출력하려면? ― struct
struct는 C 언어로 만든 구조체 이진 데이터를 처리할 때 활용하는 모듈이다. C 구조체로 만들어진 파일을 읽거나 네트워크로 전달되는 C 구조체 이진 데이터를 파이썬에서 처리…
wikidocs.net
'라이브러리&Module > 표준라이브러리' 카테고리의 다른 글
시스템의 정보를 알려면? - platform (1) | 2024.02.09 |
---|---|
수강할 과목의 순서를 구하려면?(#TopologicalSorter)(do it! 점프 투 파이썬-ch03) (0) | 2023.01.19 |
정규표현식으로 개인정보를 보호하려면?(#re)(do it! 점프 투 파이썬-ch01) (0) | 2023.01.15 |
댓글