I'm assuming that the closure
argument is a context 'cookie' for the use of the callback to get appropriate context. This is a acomon idiom for callback functions, and seems to be what's going on based on the snippets you've provided (but I don't know for sure, as I don't know anything about kcache_create()
except what you posted here).
You can use that cookie to pass a pointer to the cls_lasvm
instance you're dealing with like so:
extern "C"
double
lasvm_kcache_create_callback( int i, int j, void* closure)
{
// have to get a cls_lasvm pointer somehow, maybe the
// void* clpsure is a context value that can hold the
// this pointer - I don't know
cls_lasvm* me = reinterpret_cast<cls_lasvm*>( closure);
return me->kernel( i, j)
}
class cls_lasvm //...
{
...
// the callback that's in the class doens't need kparam
double cls_lasvm::kernel(int i, int j);
};
...
// called like so, assuming it's being called from a cls_lasvm
// member function
lasvm_kcache_t *kcache=lasvm_kcache_create(&lasvm_kcache_create_callback, this);
If I'm wrong about closure being a context cookie, then your callback function in the cls_lasvm
class needs to be static:
extern "C"
double
lasvm_kcache_create_callback( int i, int j, void* closure)
{
// if there is no context provided (or needed) then
// all you need is a static function in cls_lasvm
return cls_lasvm::kernel( i, j, closure);
}
// the callback that's in the class needs to be static
static double cls_lasvm::kernel(int i, int j, void* closure);
Note that a C callback function implemented in C++ must be extern "C"
. It may seem to work as a static function in a class because class-static functions often use the same calling convention as a C function. However, doing that is a bug waiting to happen (see comments below), so please don't - go through an extern "C"
wrapper instead.
If closure
isn't a context cookie and for some reason cls_lasvm::kernel()
can't be static then you need to come up with a way to stash a this
pointer somewhere and retrieve that pointer in the lasvm_kcache_create_callback()
function, similar to the way I did in my first example, except that pointer has to come dfrom some mechanism you devise yourself. Note that this will likely make using lasvm_kcache_create()
non-reentrant and non-threadsafe. That may or may not be a problem depending on your specific circumstances.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…