Haftalık C++ 47 – C++ Serialization/Deserialization

Merhaba sevgili yazılımperver dostlarım bir başka haftalık C++ yazım ile birlikteyiz. Bu yazımda, eminim bir çoğunuzun ihtiyacını hissettiği C++  “serialization/deserialization” ihtiyacına yardımcı olabilecek alternatiflerden birine değineceğim: Cereal Kütüphanesi. Diğer alternatifler için https://github.com/thekvs/cpp-serializers sayfasına bakabilirsiniz.

Açıkçası, uzun bir  süre önce boost kütüphanelerinin sunduğu “serialization” kabiliyetlerini kullanmıştım. Daha sonraları ise, json ve xml kütüphanelerini kullanarak, bu tarz ihtiyaçlarımı kendim, basit sınıflar yazarak giderdim.

Kişisel bir ihtiyaç için neler var diye baktığımda Cereal kütüphanesine denk geldim. Öncelikle ihtiyaçları netleştirme adına burada sıralayalım:

  • Basit bir şekilde veri yapılarının içeriklerini .json (ve ileride .xml, belki binary) dosyası olarak kaydetmek (gerek konfigürasyon gerekse veri),
  • Benzer şekilde bu tarz dosyaları okumak.

Şu an için ağ üzerinden paylaşım için bu tarz bir ihtiyacım olmadığı için çok fazla bir kısıtım yok. Bu tarz ihtiyacı olan arkadaşlar Google’ın ProtoBuf’ına göz atabilirler. Özellikle, kapsamlı veri paylaşımları için bu alternatif bana da daha çekici geliyor. Buna da bir yazımda değineceğim.

Gelelim kullanıma. Öncelikle C++ 11 destekli bir derleyiciye ihtiyacınız bulunmakta. Öncelikle https://github.com/USCiLab/cereal adresinden kütüphaneyi indirmeniz gerekmekte. Kütüphane başlık dosyalarından oluşmakta, bu sebeple ilgili başlık dosyalarını, kaynak kod içerisinden eklemeniz yeterli (cereal-1.3.2\include dizininde bulunuyor, benim indirdiğim sürüm için).

Şimdi gelelim örnek olarak saklamak istediğimiz veri yapısına bir göz atalım:

sanırım isminden ne sakladığını az çok anlamışsınızdır. Ayrıca bu veri yapısı içerisinde, bir de renk sınıfımız var o da yaklaşık aşağıdaki gibi bir sınıf:

Şimdi bunu json formatında yazmak ve okumak için ne yapacağız ona bakacağız. Öncelikli olarak, hedef veri formatına göre aşağıdaki başlık dosyalarını eklemeniz gerekiyor:

  • #include <cereal/archives/binary.hpp>
  • #include <cereal/archives/portable_binary.hpp>
  • #include <cereal/archives/xml.hpp>
  • #include <cereal/archives/json.hpp>

Daha sonra, serialization/deserialization fonksiyonlarını nasıl ve nerede yazacağınız geliyor. Cereal, bunun için bir kaç yöntem sunmakta. Detaylarına https://uscilab.github.io/cereal/serialization_functions.html sayfasında ulaşacağınız yöntemler temelde aşağıdaki yaklaşımlara dayanmakta:

  1. Sınıfa tek bir metot ekleyerek her iki işi (“serialization/deserialization”) yapmak,
  2. Sınıfa her iki işlem için ayrı ayrı metotlar eklemek,
  3. Sınıf dışında tek bir metot eklemek,
  4. Sınıfa dışında iki işlem için ayrı ayrı metotlar eklemek,

Ben burada, 3. yaklaşımı tercih ettim, orjinal sınıf içerisine  müdahale etmeden, en kısa şekilde çözmek için. Fakat, “serialization/deserialization” işlevini ayro bir sınıf içerisine ekledim. Öncelikle, Color sınıfı için nasıl bir kod parçasına ihtiyacımız var ona bakalım:

cereal::make_nvp( name, value ) ibaresi zorunlu değil fakat bunu eklerseniz, Json içerisindeki isimlendirmeleri kontrol edebilirsiniz. Yoksa varsayılan, fakat pek kullanıcı dostu olmayan bir isimlendirme ile karşılaşabilirsiniz (birazdan örnek vereceğim).

Şimdi bir de, WindowParameter sınıfı için hazırlayacağımız koda bakalım:

Yukarıdaki satırlar dışında, “serialization/deserialization” için bir satır kod yazmanıza gerek yok. Temel veri tipleri için ilave bir kod parçası eklemenize ihtiyaç yok, diğerleri için, benzer şekilde serialize fonksiyonunu tanımlamanız gerekmekte.

Son olarak gelelim asıl sınıfa:

Bu sınıf ile “serialization/deserialization” işlevi kontrol edebilirsiniz. Ayrıca, .xml vs de benzer bir sınıf ile kotarılabilir. Son olarak kullanıma bir bakalım:

Pastanın, kirazını sona bıraktık 🙂 Oluşan json dosyası nasıl oluyor ona bakalım:

Yukarıda belirttiğim cereal::make_nvp’yi kullanmazsanız, aşağıdaki gibi bir çıktı elde edersiniz:

Yukarıda bahsettiğim hususlar yanında, tiplere sürüm ekleme, türetilen sınıflar için de kabiliyetler mevcut, bunlar için de kütüphanenin sayfasına göz atabilirsiniz.

Bir sonraki yazımda görüşmek dileğiyle, bol kodlu günler diliyorum.

Kaynaklar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.