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) {
return the_Env->maybe_throw_error(ret);
}
// open questions:
// how to convert callback types in the most simple way?
static int Db_associate_callback(DB *secondary, const DBT *key, const DBT *data, DBT *result) {
Db *dbs = Db::get_Db(secondary);
return EINVAL; // Dbs->get_associate_callback(Dbs, (const Dbt *) key, (const Dbt *) data, (Dbt *) result);
// Q: 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++.
// 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
// The "fast" way. Declare an "extern C" function, and then use Dbt::get_const_Dbt() to do the conversion quickly.
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) {
// 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);
}
......@@ -62,7 +62,11 @@ class Dbt : private DBT
u_int32_t get_ulen() const { return ulen; }
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);
......@@ -109,6 +113,9 @@ class Db {
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);
/* 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:
DB *the_db;
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