C에서 데이터 구조 직렬화
저는 제 데이터 구조를 디스크에 직렬화한 다음 나중에 다시 로드할 수 있는 C 라이브러리를 원합니다.임의로 중첩된 구조를 허용해야 하며, 원형 참조가 있을 수도 있습니다.
이 도구에는 내 데이터 구조를 설명하는 구성 파일이 필요할 것으로 예상됩니다.라이브러리는 코드 생성을 사용할 수 있지만 코드 생성 없이도 이 작업을 수행할 수 있습니다.
참고 저는 데이터 이동성에 관심이 없습니다.환경이 변화하지 않도록 캐시로 사용하고 싶습니다.
감사해요.
결과.
누군가가 멋진 라이브러리인 Tpl을 제안했지만, 각각 다른 두 개의 노드를 포함하는 노드 트리와 같은 임의의 객체 그래프는 하지 않는다고 생각합니다.
또 다른 후보는 계몽주의 창 관리자의 프로젝트인 이트입니다.흥미로워 보이지만 중첩된 구조를 직렬화할 수 있는 기능은 없는 것 같습니다.
tpl을 확인해보세요.개요에서:
Tpl은 C 데이터를 직렬화하기 위한 라이브러리입니다.데이터는 자연 이진 형식으로 저장됩니다.API는 작고 "방해되지 않음"을 유지하려고 합니다.XML을 사용하는 것에 비해, tpl은 C 프로그램에서 더 빠르고 쉽게 사용할 수 있습니다.Tpl은 구조를 포함하여 여러 C 데이터 유형을 직렬화할 수 있습니다.
당신이 도서관을 요청하는 것을 알고 있습니다.찾을 수 없는 경우(::boggle::, 해결된 문제라고 생각할 수 있습니다!), 다음은 해결 방법의 개요입니다.
코드 생성기[1]를 작성하여 (런타임) 사전 처리 없이 트리/그래프를 직렬화할 수 있어야 합니다.
구조를 분석해야 typedef
핸들링?), 그리고 포함된 데이터 값을 바로 앞으로 쓰되 포인터를 조심스럽게 다루십시오.
, 대예포한인터에개체다른예(▁to:터인포▁for:
char *name;
)만 참조하면 대상 데이터를 직접 직렬화할 수 있습니다.다중 참조가 가능한 개체 및 트리의 다른 노드의 경우 포인터 구조를 나타내야 합니다.각 개체에는 포인터 대신 기록되는 일련 번호가 할당됩니다.현재 메모리 위치와 일련 번호 사이의 변환 구조를 유지합니다.포인터가 이미 할당되어 있는지 확인하고, 할당되어 있지 않으면 번호를 지정하고 해당 개체를 일련화할 수 있도록 대기열에 넣습니다.
또한 readback을 하려면 node-#/memory-location 변환 단계가 필요하며, 포인터 슬롯의 노드 번호로 노드를 재생성(잘못된 포인터, 경고)하여 각 노드가 어디에 배치되었는지 확인한 다음 구조를 다시 걸어 포인터를 수정하는 것이 더 쉬울 수 있습니다.
나는 tpl에 대해 아무것도 모르지만, 당신은 그것에 대해 돈을 벌 수 있을지도 모릅니다.
디스크/네트워크 형식은 일부 유형 정보로 구성되어야 합니다.당신은 이름을 속이는 계획이 필요할 것입니다.
루트는 이 메커니즘을 사용하여 C++에서 매우 유연한 직렬화 지원을 제공합니다.
지연 추가:위에서 말한 것처럼 이것이 항상 쉬운 것은 아니라는 생각이 듭니다.다음(의도적이고 잘못 설계된) 선언을 고려해 보십시오.
enum {
mask_none = 0x00,
mask_something = 0x01,
mask_another = 0x02,
/* ... */
mask_all = 0xff
};
typedef struct mask_map {
int mask_val;
char *mask_name;
} mask_map_t;
mask_map_t mask_list[] = {
{mask_something, "mask_something"},
{mask_another, "mask_another"},
/* ... */
};
struct saved_setup {
char* name;
/* various configuration data */
char* mask_name;
/* ... */
};
그리고 우리가 초기화한다고 가정합니다.struct saved_setup
하기 위한 항목들mask_name
점mask_list[foo].mask_name
.
연재할 요?struct saved_setup.mask_name
?
데이터 구조를 설계할 때 주의를 기울이거나 일련화 프로세스에 사례별 인텔리전스를 제공해야 합니다.
이게 제 해결책입니다.그것은 malloc, free, mmap, munmap 시스템 호출의 나만의 구현을 사용합니다.주어진 예제 코드를 따릅니다.참조: http://amscata.blogspot.com/2013/02/serialize-your-memory.html
접근 방식에서 저는 저만의 RAM 공간으로 문자 배열을 만듭니다.그런 다음 메모리를 할당하고 해제하는 기능이 있습니다.구조를 에는 터구만후든다사용여하을음데를 합니다.mmap
나는 char 배열을 파일에 씁니다.
메모리에 다시 로드하고 싶을 때마다 사용되는 기능이 있습니다.munmap
데이터 구조를 문자 배열에 다시 배치합니다.포인터에 대한 가상 주소가 있으므로 데이터 구조를 재사용할 수 있습니다.즉, 데이터 구조를 생성하고 저장한 후 로드하고 다시 편집한 후 다시 저장할 수 있습니다.
한 번 보실 수 있습니다.C 데이터 유형(내포된 구조 포함)을 저장하는 계몽 프로젝트 라이브러리입니다.계몽 프로젝트의 거의 모든 립이 알파 이전 상태에 있지만, 이미 출시되었습니다.하지만 순환 참조를 처리할 수 있을지는 잘 모르겠습니다.아마 아닐 것입니다.
HTH
당신은 gwlib을 확인해야 합니다.serializer/deserializer는 광범위하며 검사할 수 있는 광범위한 테스트가 있습니다.http://gwlib.com/
그래프 구조를 저장하는 것에 대해 말씀하시는 것 같은데, 그렇지 않다면 무시하세요...
그래프를 저장하는 경우 그래프를 인접 행렬로 변환하는 함수를 구현하는 것이 가장 좋은 방법이라고 생각합니다.그런 다음 인접 행렬을 그래프 데이터 구조로 변환하는 함수를 만들 수 있습니다.
이를 통해 다음과 같은 세 가지 이점을 얻을 수 있습니다(애플리케이션에서 문제가 될 수도 있고 문제가 되지 않을 수도 있음).
- 인접 행렬은 그래프를 만들고 저장하는 매우 자연스러운 방법입니다.
- 인접 행렬을 만들어 응용 프로그램으로 가져올 수 있습니다.
- 데이터를 의미 있는 방식으로 저장하고 읽을 수 있습니다.
저는 CS 프로젝트에서 이 방법을 사용했고 분명히 다시 할 수 있는 방법입니다.
인접 행렬에 대한 자세한 내용은 http://en.wikipedia.org/wiki/Modified_adjacency_matrix 에서 확인할 수 있습니다.
또 다른 옵션은 C에서 Apache Avro를 구현한 Avro C입니다.
다음은 Binn 라이브러리(내가 만든 것)를 사용하는 예입니다.
binn *obj;
// create a new object
obj = binn_object();
// add values to it
binn_object_set_int32(obj, "id", 123);
binn_object_set_str(obj, "name", "Samsung Galaxy Charger");
binn_object_set_double(obj, "price", 12.50);
binn_object_set_blob(obj, "picture", picptr, piclen);
// send over the network
send(sock, binn_ptr(obj), binn_size(obj));
// release the buffer
binn_free(obj);
문자열을 키로 사용하지 않으려면 정수를 키로 사용하는 binn_map을 사용할 수 있습니다.
목록도 지원되며 다음과 같은 모든 구조를 중첩할 수 있습니다.
binn *list;
// create a new list
list = binn_list();
// add values to it
binn_list_add_int32(list, 123);
binn_list_add_double(list, 2.50);
// add the list to the object
binn_object_set_list(obj, "items", list);
// or add the object to the list
binn_list_add_object(list, obj);
이론적으로 YAML은 당신이 원하는 것을 해야 합니다. http://code.google.com/p/yaml-cpp/
그것이 당신에게 효과가 있는지 저에게 알려주세요.
당신은 https://github.com/souzomain/Packer 을 사용할 수 있습니다. 이 라이브러리는 데이터를 직렬화하고 버퍼를 반환합니다.
예:
PPACKER protocol = packer_init();
packer_add_data(protocol, yourstructure, sizeof(yourstructure));
send(fd, protocol->buffer, protocol->offset, 0); //use the buffer and the size
packer_free(protocol);
다음을 사용하여 반품을 받을 수 있습니다.
recv(fd, buffer, size, 0);
size_t offset = 0;
yourstructure data = (yourstructure *)packer_get_data(buffer, sizeof(yourstructure), &offset);
언급URL : https://stackoverflow.com/questions/371371/serialize-data-structures-in-c
'IT' 카테고리의 다른 글
데이터 프레임의 모든 문자열 제거/잘라내기 (0) | 2023.07.17 |
---|---|
새로운 Firebase에서 xcode에서 다중 구성 파일을 사용하는 방법은 무엇입니까? (0) | 2023.07.17 |
모든 출력을 Bash의 파일로 리디렉션 (0) | 2023.07.12 |
git/git-shell 관련 문제를 디버그하려면 어떻게 해야 합니까? (0) | 2023.07.12 |
BsonDocument를 공식 MongoDBC# 드라이버로 강력한 형식의 객체로 변환하는 방법은 무엇입니까? (0) | 2023.07.12 |