Commit 3dc8289b authored by Bradley C. Kuszmaul's avatar Bradley C. Kuszmaul

Make the cxx callback conversion work. Addresses #226.

git-svn-id: file:///svn/tokudb@1404 c7de825b-a66e-492c-adef-691d508d4ae1
parent f3a8729e
...@@ -105,16 +105,22 @@ int Db::set_bt_compare(bt_compare_fcn_type bt_compare_fcn) { ...@@ -105,16 +105,22 @@ int Db::set_bt_compare(bt_compare_fcn_type bt_compare_fcn) {
return the_Env->maybe_throw_error(ret); return the_Env->maybe_throw_error(ret);
} }
// open questions: // Q: How to convert callback types in the most simple way?
// how to convert callback types in the most simple way? // A: (Bradley) I see three ways to do this: The issue is that we have a C++ callback function, and we want to pass it to a C function.
// The fastest way is wrong: You cannot just pass the C++ function pointer since you cannot mix function pointers to C and C++.
static int Db_associate_callback(DB *secondary, const DBT *key, const DBT *data, DBT *result) { // The "right" way is to declare an "extern C" function and do all the conversions. Create a Dbt from a DBT, and then call the C function. For returned data we would have do something too. But it turns out that DBT and Dbt pointers are interchangable so that leads to
Db *dbs = Db::get_Db(secondary); // The "fast" way. Declare an "extern C" function, and then use Dbt::get_const_Dbt() to do the conversion quickly.
return EINVAL; // Dbs->get_associate_callback(Dbs, (const Dbt *) key, (const Dbt *) data, (Dbt *) result);
extern "C" int associate_callback_c (DB*db_c, const DBT *k, const DBT *d, DBT *result) {
assert(db_c!=0);
Db *db_cxx=Db::get_Db(db_c);
assert(db_cxx);
return (*db_cxx->associate_callback_cxx)(db_cxx, Dbt::get_const_Dbt(k), Dbt::get_const_Dbt(d), Dbt::get_Dbt(result));
} }
int Db::associate(DbTxn *txnid, Db *secondary, int (*callback)(Db *secondary, const Dbt *key, const Dbt *data, Dbt *result), u_int32_t flags) { int Db::associate(DbTxn *txnid, Db *secondary, int (*callback)(Db *secondary, const Dbt *key, const Dbt *data, Dbt *result), u_int32_t flags) {
// secondary->set_associate_callback(callback); // secondary->set_associate_callback(callback);
int ret = the_db->associate(the_db, txnid->get_DB_TXN(), secondary->get_DB(), Db_associate_callback, flags); secondary->associate_callback_cxx = callback;
int ret = the_db->associate(the_db, txnid->get_DB_TXN(), secondary->get_DB(), associate_callback_c, flags);
return the_Env->maybe_throw_error(ret); return the_Env->maybe_throw_error(ret);
} }
...@@ -63,6 +63,10 @@ class Dbt : private DBT ...@@ -63,6 +63,10 @@ class Dbt : private DBT
void set_ulen(u_int32_t p) { ulen = p; } void set_ulen(u_int32_t p) { ulen = p; }
DBT *get_DBT(void) { return (DBT*)this; } DBT *get_DBT(void) { return (DBT*)this; }
const DBT *get_const_DBT(void) const { return (const DBT*)this; }
static Dbt* get_Dbt(DBT *dbt) { return (Dbt *)dbt; }
static const Dbt* get_const_Dbt(const DBT *dbt) { return (const Dbt *)dbt; }
Dbt(void */*data*/, u_int32_t /*size*/); Dbt(void */*data*/, u_int32_t /*size*/);
Dbt(void); Dbt(void);
...@@ -109,6 +113,9 @@ class Db { ...@@ -109,6 +113,9 @@ class Db {
int set_bt_compare(bt_compare_fcn_type bt_compare_fcn); int set_bt_compare(bt_compare_fcn_type bt_compare_fcn);
int associate(DbTxn *, Db *, int (*)(Db *, const Dbt *, const Dbt *, Dbt *), u_int32_t); int associate(DbTxn *, Db *, int (*)(Db *, const Dbt *, const Dbt *, Dbt *), u_int32_t);
/* the cxx callbacks must be public so they can be called by the c callback. But it's really private. */
int (*associate_callback_cxx)(Db *, const Dbt *, const Dbt *, Dbt*);
private: private:
DB *the_db; DB *the_db;
DbEnv *the_Env; DbEnv *the_Env;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment