2016-07-08 103 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