C++:приведение к аннулированию * и обратно
-
21-09-2019 - |
Вопрос
* ---Редактировать - теперь весь источник*
Когда я отлаживаю его в конце, "get" и "value" имеют разные значения!Возможно, я неправильно конвертирую в void * и возвращаюсь к User?
#include <db_cxx.h>
#include <stdio.h>
struct User{
User(){}
int name;
int town;
User(int a){};
inline int get_index(int a){
return town;
} //for another stuff
};
int main(){
try {
DbEnv* env = new DbEnv(NULL);
env->open("./",
DB_CREATE | DB_INIT_MPOOL | DB_THREAD |
DB_INIT_LOCK | DB_INIT_TXN | DB_RECOVER | DB_INIT_LOG, 0);
Db* datab = new Db(env, 0);
datab->open(NULL, "db.dbf", NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0);
Dbt key, value, get;
char a[10] = "bbaaccd";
User u;
u.name = 1;
u.town = 34;
key.set_data(a);
key.set_size(strlen(a) + 1 );
value.set_data((void*)&u);
value.set_size(sizeof(u));
get.set_flags(DB_DBT_MALLOC);
DbTxn* txn;
env->txn_begin(NULL, &txn, 0);
datab->put(txn, &key, &value, 0);
datab->get(txn, &key, &get, 0);
txn->commit(0);
User g;
g = *((User*)&get);
printf("%d", g.town);
getchar();
return 0;
}catch (DbException &e){
printf("%s", e.what());
getchar();
}
решение
создайте своего рода "сериализатор", который преобразовал бы все POD в void *, а затем объединил бы эти части
PS Или я бы переписал User в POD type, и все будет в порядке, я надеюсь.
Добавить
Это странно, но...Я привел defenetly объект, не являющийся pod, к void * и обратно (внутри него есть std::string), и все в порядке (без отправки его в базу данных и обратно).Как это могло быть?И после того, как я приведу и отправлю 'throw' db defenetly объект pod defenetly (никаких дополнительных методов, все члены pod, это простая структура {int a;int б;...}) Я получаю обратно испачканную фотографию.Что не так с моим подходом?
Добавить примерно через неделю после первого "добавления"
Черт...Я собрал их, просто чтобы посмотреть, какую грязь они возвращают, и о!все в порядке!...Я не могу !...ААа!..Господи...Разумный вопрос (в 99,999 процентах ситуаций правильный ответ - "мой", но...вот...) - кто в этом виноват?Мой или VSs?
Другие советы
Поскольку проверка возвращаемого значения put() отсутствует, вполне может быть, что произошла ошибка, которая предотвратила обновление. Документация указывает на довольно много состояний ошибки:
Вы почти наверняка НЕ должны передавать 'get' непосредственно Пользователю.Вместо этого извлеките сохраненные вами данные, а затем приведите их в действие.Мы не можем знать наверняка, пока вы не поделитесь с нами определением Dbt.Делая предположение, основанное на том, что мы может видишь:
datab->get(txn, &key, &get, 0);
void* data = get.get_data();
User g = *((User*)data);
Расскажите нам больше о Dbt, и мы, вероятно, сможем вам больше помочь.
Я бы сделал что-то вроде этого:
User user;
std::stringstream dbStotrStream;
dbStoreStream << user; // Serialize user
std::string dbStore(bdStoreStream.str());
value.set_data(dbStore.c_str());
value.set_size(dbStore.lenght());
//// Put in DB
Тогда извлечение этого будет выглядеть следующим образом:
//// Get from DB
std::string dbStore(get.get_data(),get.get_date() + get.get_size());
std::stringstream dbStoreStream(dbStore);
User outUser;
dbStoreStream >> outUSer;