Passing an argument to a void(*)(void*)

Viewed 87

I am wrapping some sqlite3 C code in C++ and am confused about this type of argument void(*)(void*) in this function

int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));

So my wrapper looks like

int Query::Blob(int index, const void* blob, int blob_size, void* memory_management){
   return sqlite3_bind_blob(stmt, index, blobl, blob_size, memory_management);
}

I should be able to pass the following to the last argument

  1. Some function to free the blob memory

  2. Either SQLITE_STATIC or SQLITE_TRANSIENT defines

The two defines are unsurprisingly defined as

typedef void (*sqlite_3_destructor_type)(void*);

But I really don't understand the void/void syntax. How can I wrap that in my C++ method to accept a function like delete or the defines?

2 Answers

The type void(*)(void*) is a pointer to a non-member function that takes a single argument of type void * and returns void.

So if your memory_management function is declared as:

void memory_management(void *);

Then it matches this definition, and Query::Blob should be defined as:

int Query::Blob(int index, const void* blob, int blob_size, void (*memory_management)(void *)){
   return sqlite3_bind_blob(stmt, index, blobl, blob_size, memory_management);
}

This means that you need to provide a call back that takes one argument, a pointer to void and returns nothing. This has to be a free function (not a non-static method of a class)

Indeed, free is such a function. You can use a delete-like as well:

void myfree(void* data)
{
    delete static_cast<MyObject*>(data);
}

You loose type-safety, but if this is to free an object passed as void* somewhere else and also used in callback, this is defined behavior.

Related