gpt4 book ai didi

c++ - 如何从 char 指针转换为自定义对象指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:56:33 27 4
gpt4 key购买 nike

我正在使用 leveldb 来存储整数和 MyClass 对象的键值对。实际上,一个键可以包含多个对象。从数据库中检索数据时出现的问题。它编译,但是 MyClass 成员的值不是我放入数据库的值。

std::string value;
leveldb::Slice keySlice = ANYKEY;
levelDBObj->Get(leveldb::ReadOptions(), keySlice, &value);

std::string value1 现在只能包含一个或多个 MyClass 对象。那么如何获得它们呢?

我已经尝试过以下方法,但没有用;

1.) 直接类型转换和memcpy

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);
}

2.) reinterpret_cast to void pointer

MyClass* obj = (MyClass*)malloc( value.size());
const void* vobj = reinterpret_cast<const void*>( value.c_str() );
int numValues = value.size()/sizeof(MyClass);
for( int i=0; i<numValues; ++i) {
const MyClass dummyObj = *(reinterpret_cast<const MyClass*>(vobj)+i);
vObjects.push_back(dummyObj);
}

MyClass 是几个公共(public)成员的集合,例如unsigned int 和 unsigned char,大小稳定。

我知道只有一个对象也有类似的问题。但在我的例子中, vector 可以包含不止一个,它来自 leveldb 数据库。

编辑:解决方案

我为 MyClass 编写了(反)序列化方法,然后使其工作。感谢提示!

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 */
}

get方法如下(put类比):

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;
}

最佳答案

你必须序列化你的类...否则,你只是占用一些内存并将其写入 leveldb。无论您取回什么,不仅会有所不同,而且可能也将完全无用。查看此问题以获取有关序列化的更多信息:How do you serialize an object in C++?

LevelDB 确实支持一个键下的多个对象,但是,尽量避免这样做,除非你有充分的理由。我建议你对每个对象进行哈希处理一个唯一的散列(如果你想要一个散列函数,请参见 Google's CityHash)并存储序列化对象及其相应的散列。如果您的对象本身就是一个集合,那么您必须将所有对象序列化为一个字节数组,并使用某种方法来确定每个对象的开始/结束位置。

更新

一个可序列化的类看起来像这样:

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;
}
};

关于c++ - 如何从 char 指针转换为自定义对象指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8990135/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com