2016-11-17 531 views
2

目前我們希望使用Redis作爲我們的應用程序的內存數據庫,同時我們也是Redis數據庫的新成員。您能否告訴我們如何在Redis中將類對象存儲爲值?我們已經嘗試將Class對象轉換爲char緩衝區,然後以字符串形式存儲到Redis數據庫中。然後從Redis中以字符串的形式檢索並將其轉換爲類對象。將字符串(從Redis檢索到)轉換爲Class對象後,我們看到的是給出一些垃圾值。如何將C++ Class對象作爲值存儲在Redis數據庫中?

那麼,您可以在這裏幫助我們。

注意:我們使用了base64_encode和base64_decode來存儲到Redis中,並且從Class對象到char緩衝區,我們使用了memcpy/reinterpret_cast。這裏的解碼和編碼工作正常,無需使用Redis數據庫。但是,一旦我們使用Redis數據庫來存儲,然後進行解碼和編碼,那麼它不起作用。

在此先感謝。

+0

的Redis不會修改您的數據。您的代碼可能存在一些問題。順便說一下,由於Redis可以保存二進制字符串,因此不需要使用base64來編碼和解碼數據。 –

+0

「我們嘗試了將Class對象轉換爲char緩衝區」< - 我懷疑這可能是問題 - 你是如何執行序列化(然後是「轉換」)的? –

+0

@for_stack和Itamar Habar,感謝您的評論,現在我們可以通過使用char緩衝區來存儲和檢索正確的對象。 –

回答

2

你用char緩衝區的方法理論上可以用簡單的類來分配堆內存(假設你處理對齊問題)。

嘗試使用一些序列化庫,如protobuf,boost :: serialization,穀類等。

這裏是cereal一個例子:

#include <cassert> 
#include <sstream> 
#include <string> 
#include <unordered_map> 

#include <hiredis/hiredis.h> 
#include <cereal/archives/binary.hpp> 
#include <cereal/types/memory.hpp> 
#include <cereal/types/unordered_map.hpp> 

class foo { 
    int i; 
    std::string s; 
    std::unordered_map<std::string, int> m; 

    friend class cereal::access; 

    template <typename Archive> 
    void serialize(Archive& archive) { 
     archive(i, s, m); 
    } 

public: 
    foo() {} 
    foo(int i, const std::string& s) : i(i), s(s) { m[s] = i; } 

    friend bool operator==(const foo& l, const foo& r) { 
     return l.i == r.i && l.s == r.s && l.m == r.m; 
    } 
}; 

int main() { 
    std::ostringstream oss; 
    cereal::BinaryOutputArchive archive{oss}; 
    foo f{10, "bar"}; 
    archive(f); 

    auto redis_context = redisConnect("127.0.0.1", 6379); 
    const auto set_reply = 
     redisCommand(redis_context, "SET key %b", oss.str().c_str(), oss.str().length()); 
    freeReplyObject(set_reply); 

    // later on 
    const auto get_reply = 
     static_cast<redisReply*>(redisCommand(redis_context, "GET key")); 
    std::string repr{get_reply->str, static_cast<size_t>(get_reply->len)}; 
    freeReplyObject(get_reply); 

    std::istringstream iss{repr}; 
    cereal::BinaryInputArchive input(iss); 
    foo g; 
    input(g); 

    assert(f == g); 

    redisFree(redis_context); 
} 
+0

感謝您的回覆,並很好地解釋。 –

相關問題