2016-11-17 19 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

感谢您的回复,并很好地解释。 –

相关问题