C ++: приведение к void * и обратно - PullRequest
3 голосов
/ 20 января 2010

* --- Редактировать - теперь весь источник *

Когда я отлаживаю его в конце, «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, и все будет хорошо, я надеюсь.

Добавить

Странно, но ... Я бросил объект, не являющийся модулем, в void * и обратно (в нем есть std :: string), и все в порядке (без отправки его в БД и обратно). Как это могло произойти? И после того, как я произвожу и отправляю «через» дБ объект «pod defenetly» (без дополнительных методов, все члены являются «pod», это простая структура {int a; int b; ...}), я получаю обратно dirted. Что не так с моим подходом?

Добавить через неделю после первого добавления '

Черт ... Я скомпилировал их, просто чтобы посмотреть, какую грязь он возвращает, и о! все нормально! ... не могу! ... Аааа ... Господи ... Резонный вопрос (в 99,999 процентах случаев правильный ответ - "мой", но ... здесь ...) - чья это вина? Мои или VS?

Ответы [ 4 ]

7 голосов
/ 20 января 2010

Если User не является POD , это не определено в C ++.

Edit:

Глядя на db_cxx.h , разве вы не должны делать вызовы get_doff(), get_dlen() и get_data() или что-то на Dbt вместо того, чтобы просто приводить (и назначать) его типу пользователя?

1 голос
/ 20 января 2010

Вы почти наверняка НЕ ​​должны разыгрывать 'get' непосредственно пользователю. Вместо этого извлеките данные, которые вы сохранили, а затем приведите их. Мы не можем знать наверняка, если вы не поделитесь с нами определением Dbt. Делая догадки, основываясь на том, что мы можем увидеть:

datab->get(txn, &key, &get, 0);
void* data = get.get_data();
User g = *((User*)data);

Расскажите нам больше о Dbt, и мы, вероятно, сможем вам помочь.

1 голос
/ 20 января 2010

Поскольку нет проверки возвращаемого значения put (), вполне может быть, что произошла ошибка, которая помешала обновлению. В документации указано довольно много ошибок:

0 голосов
/ 20 января 2010

Я бы сделал что-то вроде этого:

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