2016-07-08 104 views
1

代碼的唯一區別就是數據的初始化。這工作:Berkeley DB不能用不同的Dbt初始化設置值

 Dbt key, data(&b, sizeof(int)); 
     key.set_data(&a); 
     key.set_ulen(sizeof(int)); 
     data.set_flags(DB_DBT_USERMEM); 

但這並不:

 Dbt key, data; 
     key.set_data(&a); 
     key.set_ulen(sizeof(int)); 
     data.set_data(&b); 
     data.set_ulen(sizeof(int)); 
     data.set_flags(DB_DBT_USERMEM); 

https://docs.oracle.com/cd/E17076_04/html/api_reference/CXX/dbt.html讀文件,我沒有看到這兩種方式的區別。這很混亂。

完整的代碼和結果如下:

$ cat db.cpp 

#include <db.h> 
#include <db_cxx.h> 
#include <exception> 
#include <iostream> 
using namespace std; 

int main() { 
     Db db(NULL, 0); 
     u_int32_t oFlags = DB_CREATE | DB_TRUNCATE; 
     try { 
      db.open(NULL, "test.db", NULL, DB_HASH, oFlags, 0); 
     } catch (DbException &e) { 
      cout << "DbException" << endl; 
     } catch (std::exception &e) { 

     } 
     int a = 5, b = 6, c = 0, result[1]= {-1}; 
     Dbt key, data(&b, sizeof(int)); 
     key.set_data(&a); 
     key.set_ulen(sizeof(int)); 
     data.set_flags(DB_DBT_USERMEM); 
     cout << (db.get(NULL, &key, &data, 0) == DB_NOTFOUND) << endl; 
     cout << c << endl; 
     db.put(NULL, &key, &data, 0); 
     key.set_data(&a); 
     data.set_data(result); 
     data.set_ulen(sizeof(int)); 
     cout << (db.get(NULL, &key, &data, 0))<< endl; 
     cout << *((int *) data.get_data()) << endl; 
     cout << result[0] << endl; 
     return 0; 
} 

$ rm test.db ; g++ db.cpp -ldb_cxx-5.1; ./a.out 
1 
0 
0 
6 
6 

$ cat db.cpp 

#include <db.h> 
#include <db_cxx.h> 
#include <exception> 
#include <iostream> 
using namespace std; 

int main() { 
     Db db(NULL, 0); 
     u_int32_t oFlags = DB_CREATE | DB_TRUNCATE; 
     try { 
      db.open(NULL, "test.db", NULL, DB_HASH, oFlags, 0); 
     } catch (DbException &e) { 
      cout << "DbException" << endl; 
     } catch (std::exception &e) { 

     } 
     int a = 5, b = 6, c = 0, result[1]= {-1}; 
     Dbt key, data; 
     key.set_data(&a); 
     key.set_ulen(sizeof(int)); 
     data.set_data(&b); 
     data.set_ulen(sizeof(int)); 
     data.set_flags(DB_DBT_USERMEM); 
     cout << (db.get(NULL, &key, &data, 0) == DB_NOTFOUND) << endl; 
     cout << c << endl; 
     db.put(NULL, &key, &data, 0); 
     key.set_data(&a); 
     data.set_data(result); 
     data.set_ulen(sizeof(int)); 
     cout << (db.get(NULL, &key, &data, 0))<< endl; 
     cout << *((int *) data.get_data()) << endl; 
     cout << result[0] << endl; 
     return 0; 
} 

$ rm test.db ; g++ db.cpp -ldb_cxx-5.1; ./a.out 
1 
0 
0 
-1 
-1 

回答

1

你需要調用Dbt.set_size()Dbt.set_ulen()只設置Dbt.data指向的內存分配大小。 Dbt.size具有您的密鑰或數據的實際使用長度。添加到您的第二個例子這些電話應該使其工作:

Dbt key, data; 
    key.set_data(&a); 
    key.set_ulen(sizeof(int)); 
    key.set_size(sizeof(int)); 
    data.set_data(&b); 
    data.set_ulen(sizeof(int)); 
    data.set_size(sizeof(int)); 
    data.set_flags(DB_DBT_USERMEM); 

至於爲何Dbt key工作在所有你不set_size,我不能肯定。也許你對堆棧中未初始化的數據感到幸運?如果你想知道,你可以打印出key.size的值。

爲了清楚起見,您不需要在put()之前設置ulen。只需在設置get()之前設置它讓BDB知道它有多少內存要讀取數據。

+0

非常感謝!你真的很有幫助。 – user3458198