C++ 如何从char指针强制转换为自定义对象指针
我使用leveldb存储integer和MyClass对象的键值对。实际上,一个键可以包含多个对象。 从数据库检索数据时出现问题。它进行编译,但是MyClass成员的值不是我输入数据库的值C++ 如何从char指针强制转换为自定义对象指针,c++,serialization,casting,deserialization,leveldb,C++,Serialization,Casting,Deserialization,Leveldb,我使用leveldb存储integer和MyClass对象的键值对。实际上,一个键可以包含多个对象。 从数据库检索数据时出现问题。它进行编译,但是MyClass成员的值不是我输入数据库的值 std::string value; leveldb::Slice keySlice = ANYKEY; levelDBObj->Get(leveldb::ReadOptions(), keySlice, &value); std::stringvalue1现在只能包含一个或多个MyClass
std::string value;
leveldb::Slice keySlice = ANYKEY;
levelDBObj->Get(leveldb::ReadOptions(), keySlice, &value);
std::string
value1
现在只能包含一个或多个MyClass对象。那我怎么得到它们呢
我已经尝试了以下方法,但没有效果
1.)直接打字和记忆
std::vector<MyClass> vObjects;
MyClass* obj = (MyClass*)malloc( value.size());
memcpy((void*)obj, (void*) (value.c_str()), value.size());
MyClass dummyObj;
int numValues = value.size()/sizeof(MyClass);
for( int i=0; i<numValues; ++i) {
dummyObj = *(obj+i);
vObjects.push_back(dummyObj);
}
get
方法如下(put
类似):
int getValues(leveldb::Slice keySlice,std::vector&values)常量{
std::字符串值;
leveldb::Status Status=levelDBObj->Get(leveldb::ReadOptions(),keySlice,&value);
如果(!status.ok()){
value.clear();
返回-1;
}
int nValues=value1.size()/sizeof(CHit);
MyObj dummyObj;
对于(int i=0;i您必须序列化您的类…否则,您只需占用一些内存并将其写入leveldb。您得到的结果不仅会有所不同,而且可能也完全无用。有关序列化的更多信息,请查看此问题:
LevelDB支持一个键下的多个对象,但是,除非你有很好的理由,否则尽量避免这样做。我建议你用一个唯一的散列来散列每个对象(看看你是否想要散列函数)并存储序列化对象及其相应的哈希。如果对象本身是一个集合,则必须将所有对象序列化为一个字节数组,并使用某种方法来确定每个对象的开始/结束位置
更新
可序列化类的外观如下所示:
class MyClass
{
private:
int _numeric;
string _text;
public:
// constructors
// mutators
void SetNumeric(int num);
void SetText(string text);
static unsigned int SerializableSize()
{
// returns the serializable size of the class with the schema:
// 4 bytes for the numeric (integer)
// 4 bytes for the unsigned int (the size of the text)
// n bytes for the text (it has a variable size)
return sizeof(int) + sizeof(unsigned int) + _text.size();
}
// serialization
int Serialize(const char* buffer, const unsigned int bufferLen, const unsigned int position)
{
// check if the object can be serialized in the available buffer space
if(position+SerializableSize()>bufferLen)
{
// don't write anything and return -1 signaling that there was an error
return -1;
}
unsigned int finalPosition = position;
// write the numeric value
*(int*)(buffer + finalPosition) = _numeric;
// move the final position past the numeric value
finalPosition += sizeof(int);
// write the size of the text
*(unsigned int*)(buffer + finalPosition) = (unsigned int)_text.size();
// move the final position past the size of the string
finalPosition += sizeof(unsigned int);
// write the string
memcpy((void*)(buffer+finalPosition), _text.c_str(), (unsigned int)_text.size());
// move the final position past the end of the string
finalPosition += (unsigned int)_text.size();
// return the number of bytes written to the buffer
return finalPosition-position;
}
// deserialization
static int Deserialize(MyClass& myObject,
const char* buffer,
const unsigned int buffSize,
const unsigned int position)
{
insigned int currPosition = position;
// copy the numeric value
int numeric = *(int*)(buffer + currentPosition);
// increment the current position past the numeric value
currentPosition += sizeof(int);
// copy the size of the text
unsigned int textSize = *(unsigned int*)(buffer + currentPosition);
// increment the current position past the size of the text
currentPosition += sizeof(unsigned int);
// copy the text
string text((buffer+currentPosition), textSize);
if(currentPosition > buffSize)
{
// you decide what to do here
}
// Set your object's values
myObject.SetNumeric(numeric);
myObject.SetText(text);
// return the number of bytes deserialized
return currentPosition - position;
}
};
您还可以向我们展示一段如何编写leveldb的代码片段吗?我怀疑当您将对象放入值片时,您没有序列化它。对,我没有序列化它。我没有时间尝试它(我首先要看看如何在我的情况下这样做)。我将在明天返回代码时给出反馈;)我想避免使用boost,因为你手头没有为此而裁剪的代码?而且,我有/确实有很好的理由/使用多个对象;)好吧,如果boost不是一个选项,那么你可以。根据你的速度要求,你也可以使用JSON:(在你改变模式时,JSON更健壮,更宽容)。谢谢你的帮助。我发布了我的解决方案。@ezdazuzena刚刚添加了一个代码示例,说明了如何在没有任何第三方库的情况下使类可序列化。(编辑)刚刚看到了你的解决方案……好吧,现在有两个示例:)
void MyClass::serialize( char* outBuff ) {
memcpy(outBuff, (const void*) &aVar, sizeof(aVar));
unsigned int c = sizeof(aVar);
memcpy(outBuff+c, (const void*) &bVar, sizeof(bVar));
c += sizeof(bVAr);
/* and so on */
}
void MyClass::deserialize( const char* inBuff ) {
memcpy((void*) &aVar, inBuff, sizeof(aVar));
unsigned int c = sizeof(aVar);
memcpy((void*) &aVar, inBuff+c, sizeof(aVar));
c += sizeof(aVar);
/* and so on */
}
int getValues(leveldb::Slice keySlice, std::vector<MyObj>& values) const {
std::string value;
leveldb::Status status = levelDBObj->Get(leveldb::ReadOptions(), keySlice, &value);
if (!status.ok()) {
values.clear();
return -1;
}
int nValues = value1.size()/sizeof(CHit);
MyObj dummyObj;
for( int i=0; i<nValues; ++i) {
dummyObj.deserialize(value.c_str()+i*sizeof(MyObj));
values.push_back(dummyObj);
}
return 0;
}
class MyClass
{
private:
int _numeric;
string _text;
public:
// constructors
// mutators
void SetNumeric(int num);
void SetText(string text);
static unsigned int SerializableSize()
{
// returns the serializable size of the class with the schema:
// 4 bytes for the numeric (integer)
// 4 bytes for the unsigned int (the size of the text)
// n bytes for the text (it has a variable size)
return sizeof(int) + sizeof(unsigned int) + _text.size();
}
// serialization
int Serialize(const char* buffer, const unsigned int bufferLen, const unsigned int position)
{
// check if the object can be serialized in the available buffer space
if(position+SerializableSize()>bufferLen)
{
// don't write anything and return -1 signaling that there was an error
return -1;
}
unsigned int finalPosition = position;
// write the numeric value
*(int*)(buffer + finalPosition) = _numeric;
// move the final position past the numeric value
finalPosition += sizeof(int);
// write the size of the text
*(unsigned int*)(buffer + finalPosition) = (unsigned int)_text.size();
// move the final position past the size of the string
finalPosition += sizeof(unsigned int);
// write the string
memcpy((void*)(buffer+finalPosition), _text.c_str(), (unsigned int)_text.size());
// move the final position past the end of the string
finalPosition += (unsigned int)_text.size();
// return the number of bytes written to the buffer
return finalPosition-position;
}
// deserialization
static int Deserialize(MyClass& myObject,
const char* buffer,
const unsigned int buffSize,
const unsigned int position)
{
insigned int currPosition = position;
// copy the numeric value
int numeric = *(int*)(buffer + currentPosition);
// increment the current position past the numeric value
currentPosition += sizeof(int);
// copy the size of the text
unsigned int textSize = *(unsigned int*)(buffer + currentPosition);
// increment the current position past the size of the text
currentPosition += sizeof(unsigned int);
// copy the text
string text((buffer+currentPosition), textSize);
if(currentPosition > buffSize)
{
// you decide what to do here
}
// Set your object's values
myObject.SetNumeric(numeric);
myObject.SetText(text);
// return the number of bytes deserialized
return currentPosition - position;
}
};