C++ object serialization 란 무엇인가?

C++ object serialization 란 무엇인가?
국내에 번역된 말로는 “객체 직렬화” 라고 하는데, 우리나라말로 좀 더 풀어 보면, 객체의 메모리를 연속적인 바이트로 만들고, 만들어진 연속적인 바이트를 원래의 객체로 복원하는 작업을 말한다.
그러므로 C++ object serialize 라고 한다면, 위에서 말한 작업을 하라는 것이다.
어디에 쓰이는가?
이러한 객체 직렬화는 메모리에 있는 데이터를 스트림으로 보낼 때 사용 한다. 스트림을 이용하면 객체(객체를 아니여도 … )를 파일에/로/ 출력/입력 할 수 있으며, 네트워크에서 송수신 할 수 있으므로, 보통, 객체를 파일로 저장해서 읽으려고 할 때, 네트워크로 보내고 받을 때 이다.
개인적 사견으로는 암호화를 할 때, 사용 될 수도 있을것 같다.
여기서 잠깐 스트림에 대해서 정리하면, 스트림이란 입구와 출구가 있는 파이프 라인이다.
C++에서 어떻게 파일 스트림으로 보낼 수 있는가?
C++ 코드로 스트림화 한다면, 다음과 같을 것이다. 해당 소스 코드는
http://functionx.com/cpp/articles/serialization.htm
에서 가져 온 것이다.
츨력 예제.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <fstream>
#include <iostream>
using namespace std;
class Student
{
public:  
    char   FullName[40];  
    char   CompleteAddress[120];  
    char   Gender;  
    double Age;  
    bool   LivesInASingleParentHome;
};
int main()
{  
    Student one;  
    strcpy(one.FullName, "Ernestine Waller");  
    strcpy(one.CompleteAddress, "824 Larson Drv, Silver Spring, MD 20910");  
   
    one.Gender = 'F';  
    one.Age = 16.50;  
    one.LivesInASingleParentHome = true;      
    // output 파일 스트림을 열고
    ofstream ofs("fifthgrade.ros", ios::binary);  
   
    // 그 스트림에 Student 객체를 밀어 넣는다.
    ofs.write((char *)&one, sizeof(one));  
    return 0;
}

입력 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <fstream>
#include <iostream>
using namespace std;
class Student
{
public:  
    char   FullName[40];  
    char   CompleteAddress[120];  
    char   Gender;  
    double Age;  
   
    bool   LivesInASingleParentHome;
};
int main()
{
    Student two;  
   
    // Input 파일 스트림을 열고
    ifstream ifs("fifthgrade.ros", ios::binary);  
    // 읽은 후
    ifs.read((char *)&two, sizeof(two));  
    // 출력해 본다.
    cout << "Student Information\n";  
    cout << "Student Name: " << two.FullName << endl;  
    cout << "Address:      " << two.CompleteAddress << endl;  
   
    if( two.Gender == 'f' || two.Gender == 'F' )      
        cout << "Gender:       Female" << endl;  
    else if( two.Gender == 'm' || two.Gender == 'M' )      
        cout << "Gender:       Male" << endl;  
    else
        cout << "Gender:       Unknown" << endl;  
   
    cout << "Age:          " << two.Age << endl;  
    if( two.LivesInASingleParentHome == true )      
        cout << "Lives in a single parent home" << endl;  
    else
        cout << "Doesn't live in a single parent home" << endl;      
    cout << "\n";  
    return 0;
}

 
직렬화가 보다 직관적이다 라고 해야 할까? 그냥 메모리에 있는것을 크기만큼 write 하면 끝나고 read 하면 끝난다. 하지만 이것이 쉬운 이유는, 객체가 POD 데이터이므로 쉬웠던 것이다.
실제로 객체의 안에 컨테이너가 있거나, 동적 메모리가 올라간 형태라면 위의 방식 데로 사용 할 수 없다. 왜냐하면 포인터를 예로 들면, 포인터 4 바이트는 특정 메모리를 가리키고 있는데, 특정 메모리까지 쫒아가 write 작업을 하지 않으면 말짱 꽝이기 때문이다.
즉, 쭉정이가 된다.(껍질만 있는 곡식이나 과일을 뜻한다.)
그래서 C++ 에서 객체를 다루고자 할 때는 손이 많이 간다. 그래서 그런지 이러한 작업을 도와 주는 라이브러리가 있다.
도와주는 라이브러리는 어떤게 있는가?

  1. Google Protocol Buffer
  2. Sweet Persist
  3. s11n
  4. boost::serialize

1. Google Protocol Buffer
독자적인 스크립트 언어가 있으며, 구글에서 만들었다. 객체마다 개별적인 스크립트를 만들어야 하는 불편함과, 한 종의 객체를 여러개 연결하여 하나의 파일로 출력 할 때는, 수동으로 그 객체의 경계를 만들어 주고 읽을 때 역시 그 곙계를 끊어서 읽어줘야 한다.
스크립트로 작성된 파일은 자바, C++, 파이선 등에서 읽고 쓸 수 있도록 개별 언어마다 코드를 만들어 준다. 그러므로, .. 다른 언어간의 이식성이 무척 뛰어나다.
만약 C++ 로 쓰고, 자바로 읽어야 되는 상황이나 그 반대의 상황일 때는 1번이 좋을 것이다.
2. Sweet Persist
라이렌스가 있어, 제약이 있어 알아보지 않았다. (사용해 보지 못했다.)
3. s11n
유니코드 미지원, 바이너리 출력을 할 수 없다. 그리고 정적라이브러리만 사용 할 수 있다. 하지만, 다양한 데이터 포맷(텍스트 기반)과 DB에 쓸 수 있도록 도와 준다. (사용해 보지 못했다)
4. boost::serialize
C++에서 사용하기 쉽다. 상속 객체, 멤버 객체, 배열, 표준 컨테이너, 표준 string 객체 등을 쉽게 읽고 쓸수 있게 해주며, 텍스트, XML, 바이너리, 유니코드 등을 지원한다. : )
테스트로 사용해 보는 중이고, 이번 스터디에서 소개가 될 라이브러리 이다.
현재인 2009-10-13짜의 정보이므로, 시간이 지나면, 변경될 수 있는 점이 있으니, 한번 직접 보길 바란다.
라이브러리를 어떻게 쓰는가?
boost:serialize의 사용법 : 바이너리로 std::vector<std::vector<unsigned char>> 를 밀어 넣고 빼오기만을 만들어 보았다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream> // 화면에 보여 주기 위해
#include <fstream> // 파일 입출력 하기 위해
#include <boost/shared_ptr.hpp> // 최적화를 위해
#include <boost/foreach.hpp> // foreach 는 이제 지겹다.
#include <boost/archive/binary_iarchive.hpp> // 바이너리 형태로 입력하기 위해
#include <boost/archive/binary_oarchive.hpp> // 바이너리 형태로 출력하기 위해
#include <boost/serialization/vector.hpp> // 직렬화 vector를 사용하기 위해
template <typename ELEMENT, template <typename T, typename ALLOC = std::allocator<T> > class CON>
class fixel_table
{
public:
    typedef CON<ELEMENT> table_col;
    typedef typename CON<table_col>::iterator iterator;
    typedef typename CON<table_col>::const_iterator const_iterator;
public:
    explicit fixel_table( size_t col, size_t row, ELEMENT e )
    {
        table_col d( col, e ); // 열을 만듬
        table_.resize( row, d ); // 만든 열로, 행을 만듬
    }
    fixel_table()
    {
    }
    iterator begin()
    {
        return table_.begin();
    }
    iterator end()
    {
        return table_.end();
    }
    const iterator begin() const
    {
        return table_.begin();
    }
    const iterator end() const
    {
        return table_.end();
    }
    table_col& operator[]( size_t y )
    {
        return table_[y];
    }
private:
    friend class boost::serialization::access;
    friend std::ostream & operator<<( std::ostream &os, const fixel_table & t);
    template <typename Archive>
    void serialize( Archive &ar, const unsigned int version )
    {
        ar & table_;
    }
    
private:
    CON< table_col > table_;
};
typedef boost::shared_ptr< fixel_table<unsigned char, std::vector> > shp_fixel_table;
shp_fixel_table new_fixel_table( size_t x, size_t y )
{
    return shp_fixel_table( new fixel_table<unsigned char, std::vector>( x , y , 'O') );
}
// ... 결국 unsigned char 를 쓰긴 했으나, 좀더 하면 요소로 뺄 수 있음
// 귀찮아서 ...
void set_fixel_table( shp_fixel_table t, size_t x, size_t y, unsigned char color )
{       
    ((*t)[y])[x] = color;
}
void print_fixel_table( shp_fixel_table t )
{
    typedef shp_fixel_table::value_type::table_col table_col;
    typedef table_col::value_type value_type;
    BOOST_FOREACH( table_col & col, *t )
    {
        BOOST_FOREACH( value_type v , col )
        {
            std::cout << v << " ";
        }
        std::cout << std::endl;
    }
}   
void save_fixel_table( shp_fixel_table t, char * filename )
{
    std::ofstream ofs( filename, std::ios_base::binary );
    boost::archive::binary_oarchive oa( ofs );
    oa << *t;
}
void restore_fixel_table( shp_fixel_table t, char * filename )
{
    std::ifstream ofs( filename, std::ios_base::binary );
    boost::archive::binary_iarchive ia( ofs );
    ia >> *t;
}
int main( void )
{   
    // 1. 픽셀 테이블을 생성하여 값을 셋팅한다
    shp_fixel_table t = new_fixel_table( 10, 10 );
    set_fixel_table( t, 4, 3, 'R' );
    // 2. 출력 하고
    print_fixel_table( t );
    // 3. 저장 한다.
    save_fixel_table( t, "test" );
    std::cout << std::endl;
    // 4. 새로운 픽셀 테이블을 만들고
    shp_fixel_table new_t = new_fixel_table(0, 0);
    restore_fixel_table( new_t, "test" );
    // 5. 잘 되었는지 확인해 본다.
    print_fixel_table( new_t );
    return 0;
}

… 익히는게 어렵지 않고, 샘플 코드도 많이 제공 하고 있으니, 영어를 못한다고 해도 크게 무리가 되진 않는다.
boost::serialize 에서 어떻게 바이너리인 메모리 데이터가 문자로 바뀔 수 있을까?
<정리중>
boost::serialize 에서 직렬된 바이너리/텍스트 의 크기가 얼마나 되는지 어떻게 알 수 있을까?
<정리중>
boost::serialize 에서 직렬 시킬 대상을 파일/스트링을 제외하고, 메모리에 어떻게 바로 저장 할 수 있을까요?

“C++ object serialization 란 무엇인가?”의 33개의 댓글

  1. Do you mind if I quote a couple of your posts as
    long as I provide credit and sources back to your site?
    My blog is in the exact same area of interest as yours and my users
    would really benefit from some of the information you present here.
    Please let me know if this okay with you. Cheers!

  2. I got this website from my buddy who shared with me regarding this web site and now this time
    I am browsing this web site and reading very informative articles or reviews at this place.

  3. I simply want to tell you that I’m all new to blogging and site-building and actually savored your blog site. Probably I’m want to bookmark your blog post . You amazingly have wonderful writings. Kudos for sharing your webpage.

  4. Hmm it appears like your website ate my first comment (it was super long) so I guess I’ll just sum it up what I had written and say, I’m thoroughly enjoying your blog. I as well am an aspiring blog blogger but I’m still new to everything. Do you have any points for novice blog writers? I’d certainly appreciate it.

  5. I’m really loving the theme/design of your site. Do you ever run into any web browser compatibility problems? A small number of my blog audience have complained about my site not working correctly in Explorer but looks great in Opera. Do you have any advice to help fix this issue?

  6. Can I just state what an alleviation to find somebody that in fact recognizes what theyre speaking about on the internet. You definitely understand just how to bring a problem to light and make it essential. Even more individuals require to read this and also comprehend this side of the tale. I cant think youre not much more preferred because you certainly have the gift.

  7. I?m amazed, I must state. Actually hardly ever do I come across a blog site that?s both enlightening as well as entertaining, and also let me tell you, you have struck the nail on the head. Your concept is superior; the concern is something that inadequate people are talking wisely around. I am very pleased that I came across this in my search for something relating to this.

  8. When I initially commented I clicked the -Notify me when new comments are added- checkbox and currently each time a remark is included I get 4 e-mails with the very same remark. Is there any way you can eliminate me from that service? Thanks!

  9. I?d need to get in touch with you right here. Which is not something I generally do! I take pleasure in checking out an article that will make people think. Additionally, many thanks for permitting me to comment!

  10. Youre so trendy! I don’t suppose Ive review anything similar to this prior to. So nice to find someone with some initial ideas on this subject. realy thanks for beginning this up. this internet site is something that is required on the internet, someone with a little creativity. useful work for bringing something new to the web!

  11. Oh my goodness! an amazing write-up man. Thanks However I am experiencing issue with ur rss. Don?t know why Unable to register for it. Is there anybody obtaining the same rss trouble? Anyone who understands kindly react. Thnkx

  12. I?d need to talk to you here. Which is not something I usually do! I take pleasure in checking out a blog post that will certainly make individuals think. Additionally, thanks for permitting me to comment!

  13. Youre so cool! I don’t intend Ive review anything similar to this prior to. So good to find somebody with some original thoughts on this subject. realy thanks for starting this up. this web site is something that is needed on the internet, someone with a little creativity. helpful work for bringing something brand-new to the net!

  14. Can I just say what an alleviation to discover somebody that in fact understands what theyre discussing online. You definitely recognize exactly how to bring a concern to light as well as make it vital. Even more individuals require to read this and recognize this side of the story. I cant think youre not much more popular because you most definitely have the present.

  15. I was very delighted to locate this web-site. I wanted to thanks for your time for this fantastic read!! I absolutely appreciating every little of it as well as I have you bookmarked to look into brand-new stuff you post.

  16. Oh my benefits! an incredible write-up guy. Thanks However I am experiencing concern with ur rss. Don?t know why Incapable to register for it. Is there anyone getting identical rss issue? Anyone who recognizes kindly respond. Thnkx

  17. Oh my goodness! an incredible post man. Thanks However I am experiencing concern with ur rss. Don?t recognize why Unable to register for it. Exists any individual obtaining similar rss trouble? Any person that recognizes kindly respond. Thnkx

  18. Sweet blog! I found it while surfing around on Yahoo News. Do you have any suggestions on how to get listed in Yahoo News? I’ve been trying for a while but I never seem to get there! Thank you

댓글 남기기