目前我们希望使用Redis作为Application的内存数据库,我们也是Redis数据库的新手。您能告诉我们如何将Class对象存储为Redis中的值。我们尝试将Class对象转换为char缓冲区,然后以字符串形式存储到Redis数据库中。然后从Redis中检索为字符串并将其转换为类对象。在将字符串(从Redis检索到)转换为Class对象之后,我们看到的是给出了一些垃圾值。
那么,请你帮我们。
注意:我们使用base64_encode和base64_decode存储到Redis中,从Class对象存储到char缓冲区,我们使用了memcpy / reinterpret_cast。这里解码和编码工作正常,而不使用Redis数据库。但是,一旦我们使用Redis数据库进行存储然后进行解码和编码,那么它就无法正常工作。
先谢谢。
答案 0 :(得分:2)
使用char缓冲区的方法理论上可以处理不分配堆内存的简单类(假设您处理对齐问题)。
尝试使用一些序列化库,例如protobuf,boost :: serialization,grain等。
以下是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);
}