문제

나는 작은 계층 구조체의할 필요가 있는 직렬화 및 전송을 통해 소켓 연결합니다.요 모두에게 직렬화를 직렬화에 따라 그것이 어떤 종류입니다.이 있는 이렇게 할 수 있는 쉬운 방법에서는 C++(이 있으므로 자바에서는)?

이 있습 C++직렬화를 온라인 코드 샘플이나 자?

편집: 그걸 분명히 하기 위해서,내가 찾는 방법에서 변환하는 개체는 바이트 배열을,그 다음으로 다시 개체입니다.저는 처리할 수 있는 소켓을 전송합니다.

도움이 되었습니까?

해결책

에 대해 얘기 직렬화를 사용할 경우, 부 serialization API 가 제 마음속에 떠오릅니다.으로 전달을 위해 이 데이터를 직렬화하고,네트워크를 통해 나는 사용하거나 Berkeley 소켓이나 asio 라이브러리.

편집:
하려면 직렬화하는 개체를 바이트 배열을 사용할 수 있습 향상 serializer 다음과 같은 방법으로(촬영에서의 튜토리얼 사이트):

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
class gps_position
{
private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & degrees;
        ar & minutes;
        ar & seconds;
    }
    int degrees;
    int minutes;
    float seconds;

public:
    gps_position(){};
    gps_position(int d, int m, float s) :
    degrees(d), minutes(m), seconds(s)
    {}
};

실제 직렬화입니다 그럼 아주 쉽게:

#include <fstream>
std::ofstream ofs("filename.dat", std::ios::binary);

    // create class instance
    const gps_position g(35, 59, 24.567f);

    // save data to archive
    {
        boost::archive::binary_oarchive oa(ofs);
        // write class instance to archive
        oa << g;
        // archive and stream closed when destructors are called
    }

직렬화에서 작동하는 것과 유사합니다.

도 있는 메커니즘에 처리할 수 있도록 직렬화의 포인터(복잡한 데이터 구조는 다음과 같 머릿 등은 문제 없음),파생된 클래스고 선택할 수 있는 사진과 텍스트 serialization.게다가 모든 STL 컨테이너을 지원합니다.

다른 팁

어떤 경우에,다룰 때는 단순한 형태,당신은 할 수 있습니다:

object o;
socket.write(&o, sizeof(o));

의 확인 증거로의 개념 또는 첫번째 초고,그래서 다른 회원의 팀이 작업을 유지할 수 있습니 다른 부분입니다.

그러나 조만간, 일반적으로 더 빨리, 이에 당신을 얻을 것이 상처!

문제가 있으:

  • 가상의 포인터가 테이블이 손상됩니다.
  • 포인터(데이터/원/능)이 손상됩니다.
  • 차이에서 패딩을 선형에서 다른 기계입니다.
  • 큰/작은-Endian 바이트 문제입니다.
  • 변형의 구현에서 떠/두 배.

(플러스 당신은 무엇을 알 필요가 있는 개봉으로 수신 측에서.)

을 향상시킬 수 있습에 이를 개발하여 자신의 마샬링/작성된 방법에 대한 모든 클래스입니다.(이상적상,그래서 그들은 확장 할 수 있습에 하위 클래스.) 몇 가지 간단한 매크로를 당신이 당신을 작성하는 다른 기본적인 유형이 매우 빨리 큰/little-endian 중립적인 순서입니다.

하지만 그런 종류의 단순한 일이 훨씬 더 나은,더 쉽게,을 통해 처리 후원의 직렬화 라이브러리.

직렬화를 돌리는 것을 의미한 개체 바이너리로 데이터입니다.는 직렬화를 의미를 재현하는 객체에서 데이터입니다.

면 직렬화를 추진 바이트로 uint8_t 벡터입니다.때 unserializing 읽고 있는 바이트로부터 uint8_t 벡터입니다.

가 확실히 패턴을 활용할 수 있를 직렬화하면 물건입니다.

각 serializable 클래스가 있어야 serialize(std::vector<uint8_t> &binaryData) 또는 이와 유사한 signatured 는 기능을 쓸 것이다 이진 표현으로 제공하는 벡터입니다.그런 다음 이 기능을 전달할 수 있습니다 이 벡터 아래로 그것은 구성원의 직렬화 기능을 그래서 그들은 쓸 수 있는 그들의 재료로습니다.

이후 데이터 표현할 수 있는 다른 다른 아키텍처를 활용할 수 있다.를 찾을 필요가 밖으로 구성표는 방법을 나타내는 데이터입니다.

자 기초부터 시작하기:

정수 데이터를 직렬화

성 바이트에서 작은 endian 다.또는 사용 varint 표현하는 경우 크기는 중요합니다.

에서 직렬화를 조금 endian 기:

data.push_back(integer32 & 0xFF);
data.push_back((integer32 >> 8) & 0xFF);
data.push_back((integer32 >> 16) & 0xFF);
data.push_back((integer32 >> 24) & 0xFF);

직렬화에서 엔디안 순서는:

integer32 = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);

직렬화 부동 소수점 데이터

내가 알기로는 IEEE754 가 독점이 여기에.지 알아의 모든 주류는 아키텍처를 사용하는 것에 대해 뭔가를 떠 버리는 경우가 있습니다.수있는 유일한 것 다른 것은 바이트다.어떤 아키텍처를 사용 작 endian,다른 사람을 사용하 big endian 바이트다.이미 주의해야하는 당신을 위해 큰 소리로 최대 바이트에서 책임지지 않습니다.또 다른 차이를 처리할 수 있습의 비정상과 무한대와 할머니는 값이다.하지만 오랫동안 당신이 피하기 위해 이러한 값을 확인해야합니다.

Serialization:

uint8_t mem[8];
memcpy(mem, doubleValue, 8);
data.push_back(mem[0]);
data.push_back(mem[1]);
...

직렬화는 그 일을 뒤로 이동합니다.마음 바이트의 순서는 아키텍처!

직렬화 문자열

처음에 동의해야에서 인코딩이 있습니다.UTF-8 일반적입니다.다음으로 저장 길이 앞으로:첫 번째 저장할 문자열의 길이를 사용하는 방법을 내가 위에서 언급된,다음 쓰는 문자열 바이트.

직렬화 배열입니다.

그들은 같은 문자열입니다.당신이 첫 번째 직렬화의 정수를 나타내는 배열의 크기는 직렬화때 각각의 물체에습니다.

Serialize 전체

내가 전에 말했듯이 그들야 serialize 방법 콘텐츠를 추가하는 벡터입니다.을 unserialize 객체가 있어야 한다고 생성자는 바이트다.할 수 있는 istream 하지만 가장 간단한 경우 그것을 할 수 있습 단지 참조 uint8_t 포인터이다.생성자를 읽는 바이트를 원하는 스트림에서 설정의 필드에서 객체입니다.는 경우 이 시스템은 잘 설계되고 직렬화 분야에서 객체를 필드를 주문할 수 있습니다 그냥 통과하면 스트림 분야의 생성자에 이니셜라이저 목록과 그들이 병렬화된 올바른 순서로 정렬됩니다.

직렬화 개체 그래프

먼저 당신이 필요가 있는지 확인하는 경우 이러한 물체를 정말로 뭔가를 당신이 원하는 직렬화됩니다.당신이 필요가 없는 직렬화들의 인스턴스가 있는 경우 이러한 물체에 존재하는 곳입니다.

지금 당신은 당신이 필요로 직렬화하는 개체가 가리키는 포인터이다.문제는 포인터의 유효한지만 프로그램에서 사용하는 그들.할 수 없는 직렬화를 포인터,당신은 당신을 중지해야에서 그들을 사용하여 개체입니다.대신 개체를 만들 수 있습니다.이 개체 수영장은 기본적으로 동적 배열을 포함하는"박".이러한 상자에 대한 참조가 있는 계산합니다.Non-zero 참조 횟수를 나타내는 살체,제로 나타냅 빈 슬롯이 있습니다.그럼 만들면 똑똑한 포인터 유사 shared_ptr 하지 않는 저장하는 개체에 대한 포인터이지만,인덱스 array.당신이 또한 필요에 동의하는 색인을 나타내는 null 포인터,예를 들어,.-1 입니다.

기본적으로 우리가 여기에 대체하는 포인터 배열의 인덱스입니다.지금 할 때 직렬화할 수 있는 직렬화 이 배열로 인하다.당신이 필요하지 않을 경우에 대해 걱정할 필요가 없는 객체를 메모리에서 대상 시스템입니다.단지 그들이 동일한 개체습니다.

그래서 우리는 직렬화하는 개체를 수 있습니다.그러나 어떤 것입니까?잘 직렬화할 때는 객체 그래프는지를 직렬화하는 개체를 직렬화하는 전체 시스템입니다.이 의미는 직렬화 시스템의 안에서 시작 부분의 시스템입니다.해당 개체에 대해 걱정하지 마십시 나머지 부분들이 시스템의 필요를 직렬화하는 배열 색인이고 그것입니다.당신이 있어야 시스템 serializer 일상적인 오케스트레이션하는 직렬화 시스템의 안내를 통해 관련된 개체는 풀과 직렬화 모니다.

에서 모든 배열에 있는 객체에는 deserialize,재현하는 객체 그래프입니다.

직렬화 기능 포인터

저장하지 않는 점에서 객체입니다.정적 배열을 포함하는 포인터를 이러한 기능 및 저장소에서 인덱스 개체입니다.

이 두 프로그램이블로 컴파일 themshelves,를 사용하여 인덱스 작업해야 합니다.

직렬화형성 유형

이 말은 당신이 피해야에서 포인터가 직렬화 유형을 사용해야 하는 배열 색인 대신,다형성은 단지 작동할 수 없기 때문에,그것은 필요 포인터입니다.

당신이 주위 유형으로 범주 및 노동 조합.

버전 관리

상단에 있습니다.할 수 있습 다른 버전의 소프트웨어 상호 운용.

이 경우에는 각 객체를 작성해야 버전 번호를 시작 부분에서의 자신의 직렬화를 나타내는 버전입니다.

적재할 때는 최대 객체에서 다른 쪽,새로운 객체를 어쩌면을 처리할 수 있 오래된 표현을 하지만 오래된 것을 처리할 수 없는 새로운 그래서 그들은 예외를습니다.

각 시간에는 무언가를 변경해야 합 범 버전 번호입니다.


그래서 하이 serialization 복잡할 수 있습니다.하지만 다행히 당신이 필요가 없는 직렬화 모두에서 당신의 프로그램은 대부분만 프로토콜은 메시지를 직렬화,종종 평범한 오래된 구조체.그래서 당신은 필요하지 않은 복잡한 트릭 위에서 언급했듯이 너무 많습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top