Salut a tous ! J'ai écrit un petit wrapper en C++/CLI pour la base de données Berkeleydb, mon wrapper est composé d'une classe native DBWrapper et d'une class managé BerkeleyDBWrapper. A l'utilisation aucune exception n'est levé mais quand j'essaie de récupérer les données que j'ai mis dans la db elle sont faussées. Par exemple j'y entrequand je récupére les données en entrant la clef Teddy je n'obtient pas 12 (j'utilise des unsigned long int comme valeur) mais un nombre par exemple 14512545654 donc rien a voir. J'ai donc pensé que le problème venait de ma classe native puisque c'est elle qui gère la db, j'ai donc écrit un programme C++ l'utilisant et la aucune problème pour récupérer mes données
Code : Sélectionner tout - Visualiser dans une fenêtre à part Clef => Teddy, Valeur => 12
. Le problème viens donc du passage du managé au natif, sa fait 2 jours que je tourne en rond et j'ai besoin d'un coup de main car je ne vois pas ce qui cloche.
voici mon class native (fichier H)
son implémentation :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 class DBWrapper { private: char db_name[512+1]; unsignedlongint db_cache_gbyte; unsignedlongint db_cache_size; int db_cache_number; int db_type; // 1 is BTree, 2 is Hash, 3 is Queue, 4 is Recno bool db_use_transaction; char db_err_file[512+1]; // The error file public: DBWrapper(); DBWrapper(char * _db_name, unsignedlongint db_cache_gbyte, unsignedlongint db_cache_size, int db_cache_number, int db_type, bool db_use_transaction, char * _db_err_file); bool OpenDatabase(); bool CloseDatabase(); bool AddData(char * key, unsignedlongint value); bool AddData(unsignedlongint key, char * value); void GetData (char * pData, int nbr, unsignedlongint key); unsignedlongint GetData(char * key); bool DeleteData(unsignedlongint key); bool DeleteData(char * key); ~DBWrapper(); };
-----
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250 #pragma comment (lib, "libdb46.lib") #include <db_cxx.h> #include "DBWrapper.h" using namespace std; // Db objects Db db(NULL, 0); // Database object u_int32_t oFlags = DB_CREATE|DB_THREAD; // Open flags; // ========== // Constructeurs DBWrapper::DBWrapper() { } DBWrapper::DBWrapper(char * _db_name, unsigned long int db_cache_gbyte, unsigned long int db_cache_size, int db_cache_number, int db_type, bool db_use_transaction, char * _db_err_file) { strcpy_s(this->db_name, strlen(_db_name)+1, _db_name); this->db_cache_gbyte = db_cache_gbyte; this->db_cache_size = db_cache_size; this->db_cache_number = db_cache_number; this->db_type = db_type; this->db_use_transaction = db_use_transaction; strcpy_s(this->db_err_file, strlen(_db_err_file)+1, _db_err_file); } // ========== // Fonctions bool DBWrapper::OpenDatabase() { try { std::cout << "Dbname " << this->db_name << std::endl; if (strlen(this->db_name) < 2) { throw new std::exception("Database name is unset"); } // Set error file //std::ofstream Error(this->db_err_file,std::ios::out); //db.set_error_stream(&Error); // Set database cache db.set_cachesize(this->db_cache_gbyte, 1024 * this->db_cache_size, this->db_cache_number); // Open the database // transaction not yet implemented switch(this->db_type) { case 1: if (this->db_use_transaction) db.open(NULL, this->db_name, NULL, DB_BTREE, oFlags, 0); else db.open(NULL, this->db_name, NULL, DB_BTREE, oFlags, 0); break; case 2: if (this->db_use_transaction) db.open(NULL, this->db_name, NULL, DB_HASH, oFlags, 0); else db.open(NULL, this->db_name, NULL, DB_HASH, oFlags, 0); break; case 3: if (this->db_use_transaction) db.open(NULL, this->db_name, NULL, DB_QUEUE, oFlags, 0); else db.open(NULL, this->db_name, NULL, DB_QUEUE, oFlags, 0); break; case 4: if (this->db_use_transaction) db.open(NULL, this->db_name, NULL, DB_RECNO, oFlags, 0); else db.open(NULL, this->db_name, NULL, DB_RECNO, oFlags, 0); break; default: throw new std::exception("Database name is unset"); break; } return true; } catch(DbException &e) { std::cout << e.what() << std::endl; } catch(std::exception &e) { std::cout << e.what() << std::endl; } return false; } bool DBWrapper::CloseDatabase() { try { db.close(0); return true; } catch(DbException &e) { std::cout << e.what() << std::endl; } catch(std::exception &e) { std::cout << e.what() << std::endl; } return false; } bool DBWrapper::AddData(char * key, unsigned long int value) { try { Dbt _key(key, strlen(key)+1); Dbt _value(&value, sizeof(unsigned long int)); int exist = db.put(NULL, &_key, &_value, DB_NOOVERWRITE); if (exist == DB_KEYEXIST) { std::cout << "This record already exist" << std::endl; } return true; } catch(DbException &e) { std::cout << e.what() << std::endl; } catch(std::exception &e) { std::cout << e.what() << std::endl; } catch(...) { std::cout << "Error" << std::endl; } return false; } bool DBWrapper::AddData(unsigned long int key, char * value) { try { Dbt _value(&key, sizeof(unsigned long int)); Dbt _key(value, strlen(value)+1); int exist = db.put(0, &_key, &_value, DB_NOOVERWRITE); if (exist == DB_KEYEXIST) { std::cout << "This record already exist" << std::endl; } return true; } catch(DbException &e) { std::cout << e.what() << std::endl; } catch(std::exception &e) { std::cout << e.what() << std::endl; } return false; } void DBWrapper::GetData (char * pData, int nbr, unsigned long int key) { try { Dbt _key; Dbt data; _key.set_data(&key); _key.set_size(sizeof(unsigned long int)); data.set_data(pData); data.set_ulen(nbr); data.set_flags(DB_DBT_USERMEM); int state = db.get(NULL, &_key, &data, 0); if (state == DB_NOTFOUND) { strcpy_s(pData, 10, "not found"); return; } } catch(DbException &e) { std::cout << e.what() << std::endl; } catch(std::exception &e) { std::cout << e.what() << std::endl; } } unsigned long int DBWrapper::GetData(char * key) { try { Dbt _key; Dbt data; unsigned long int xdata; _key.set_data(key); _key.set_ulen(strlen(key)+1); data.set_data(&xdata); data.set_size(sizeof(unsigned long int)); data.set_flags(DB_DBT_USERMEM); int state = db.get(NULL, &_key, &data, 0); return xdata; } catch(DbException &e) { std::cout << e.what() << std::endl; } catch(std::exception &e) { std::cout << e.what() << std::endl; } return 0; } bool DBWrapper::DeleteData(unsigned long int key) { try { Dbt _key; _key.set_data(&key); _key.set_size(sizeof(unsigned long int)); db.del(NULL, &_key, 0); return true; } catch(DbException &e) { std::cout << e.what() << std::endl; } catch(std::exception &e) { std::cout << e.what() << std::endl; } return false; } bool DBWrapper::DeleteData(char * key) { try { Dbt _key; _key.set_data(key); _key.set_ulen(strlen(key)+1); db.del(NULL, &_key, 0); return true; } catch(DbException &e) { std::cout << e.what() << std::endl; } catch(std::exception &e) { std::cout << e.what() << std::endl; } return false; } DBWrapper::~DBWrapper() { db.close(0); }
Ma classe managé (fichier H)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 // BerkeleyDBWrapper.h using namespace System; namespace BerkeleyDBWrapper { public ref class BerkeleyDB { public: BerkeleyDB(); BerkeleyDB(System::String^ db_name, System::UInt32^ db_cache_gbyte, System::UInt32^ db_cache_size, System::Int32^ db_cache_number, System::Int32^ db_type, System::Boolean^ db_use_transaction, System::String^ db_err_file); System::Boolean OpenDatabase(); System::Boolean CloseDatabase(); System::Boolean AddData(System::String^ key, System::UInt32^ value); System::Boolean AddData(System::UInt32^ key, System::String^ value); System::UInt32 GetData(System::String^ key); System::String^ GetData(System::UInt32^ key); System::Boolean DeleteData(System::String^ key); System::Boolean DeleteData(System::UInt32^ key); private: ~BerkeleyDB(); }; }
Son implémentation :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 // Il s'agit du fichier DLL principal. #include "DBWrapper.h" #include "BerkeleyDBWrapper.h" using namespace BerkeleyDBWrapper; // Wrapper object DBWrapper * wrapper; // ========== // Constructeurs BerkeleyDB::BerkeleyDB() { } BerkeleyDB::BerkeleyDB(System::String^ db_name, System::UInt32^ db_cache_gbyte, System::UInt32^ db_cache_size, System::Int32^ db_cache_number, System::Int32^ db_type, System::Boolean^ db_use_transaction, System::String^ db_err_file) { char * _db_name = static_cast<char *>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(db_name).ToPointer()); char * _db_err_file = static_cast<char *>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(db_err_file).ToPointer()); wrapper = new DBWrapper( _db_name, Convert::ToUInt32(db_cache_gbyte), Convert::ToUInt32(db_cache_size), Convert::ToInt32(db_cache_number), Convert::ToInt32(db_type), Convert::ToBoolean(db_use_transaction), _db_err_file); System::Runtime::InteropServices::Marshal::FreeHGlobal(safe_cast<IntPtr>(_db_name)); System::Runtime::InteropServices::Marshal::FreeHGlobal(safe_cast<IntPtr>(_db_err_file)); } // ========== // Functions System::Boolean BerkeleyDB::OpenDatabase() { bool state = wrapper->OpenDatabase(); if (state) { return Convert::ToBoolean(gcnew System::String("true")); } else { return Convert::ToBoolean(gcnew System::String("false")); } } System::Boolean BerkeleyDB::CloseDatabase() { bool state = wrapper->CloseDatabase(); if (state) { return Convert::ToBoolean(gcnew System::String("true")); } else { return Convert::ToBoolean(gcnew System::String("false")); } } System::Boolean BerkeleyDB::AddData(System::String^ key, System::UInt32^ value) { char * x_key = static_cast<char *>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(key).ToPointer()); bool state = wrapper->AddData(x_key, Convert::ToUInt32(value)); System::Runtime::InteropServices::Marshal::FreeHGlobal(safe_cast<IntPtr>(x_key)); if (state) { return Convert::ToBoolean(gcnew System::String("true")); } else { return Convert::ToBoolean(gcnew System::String("false")); } } System::Boolean BerkeleyDB::AddData(System::UInt32^ key, System::String^ value) { char * x_value = static_cast<char *>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(value).ToPointer()); bool state = wrapper->AddData(Convert::ToUInt32(key), x_value); System::Runtime::InteropServices::Marshal::FreeHGlobal(safe_cast<IntPtr>(x_value)); if (state) { return Convert::ToBoolean(gcnew System::String("true")); } else { return Convert::ToBoolean(gcnew System::String("false")); } } System::String^ BerkeleyDB::GetData(System::UInt32^ key) { char data[2048+1]; wrapper->GetData(data, 2048+1, Convert::ToUInt32(key)); return gcnew System::String(data); } System::UInt32 BerkeleyDB::GetData(System::String^ key) { char * x_key = static_cast<char *>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(key).ToPointer()); unsigned long int result = wrapper->GetData(x_key); System::Runtime::InteropServices::Marshal::FreeHGlobal(safe_cast<IntPtr>(x_key)); return Convert::ToUInt32(result.ToString()); } System::Boolean BerkeleyDB::DeleteData(System::String^ key) { char * x_key = static_cast<char *>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(key).ToPointer()); bool state = wrapper->DeleteData(x_key); System::Runtime::InteropServices::Marshal::FreeHGlobal(safe_cast<IntPtr>(x_key)); if (state) { return Convert::ToBoolean(gcnew System::String("true")); } else { return Convert::ToBoolean(gcnew System::String("false")); } } System::Boolean BerkeleyDB::DeleteData(System::UInt32^ key) { bool state = wrapper->DeleteData(Convert::ToUInt32(key)); if (state) { return Convert::ToBoolean(gcnew System::String("true")); } else { return Convert::ToBoolean(gcnew System::String("false")); } } BerkeleyDB::~BerkeleyDB() { if (wrapper) { wrapper->CloseDatabase(); delete wrapper; } }
Si vous y voyez une erreur !!!
Merci de votre aide![]()
Partager