Я предполагаю, что аргумент closure
является контекстом «cookie» для использования обратного вызова для получения соответствующего контекста. Это идиома acomon для функций обратного вызова, и похоже, что происходит на основе предоставленных вами фрагментов (но я точно не знаю, поскольку ничего не знаю о kcache_create()
, кроме того, что вы разместили здесь ).
Вы можете использовать этот файл cookie для передачи указателя на экземпляр cls_lasvm
, с которым вы имеете дело, следующим образом:
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);
Если я ошибаюсь из-за того, что замыкание является файлом cookie контекста, ваша функция обратного вызова в классе cls_lasvm
должна быть статической:
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);
Обратите внимание, что функция обратного вызова C, реализованная в C ++ , должна быть extern "C"
. Может показаться, что он работает как статическая функция в классе, потому что статические функции класса часто используют то же соглашение о вызовах, что и функция C. Однако, это ошибка, ожидающая своего появления (см. Комментарии ниже), поэтому, пожалуйста, не надо - вместо этого пройдите через оболочку extern "C"
.
Если closure
не является файлом cookie контекста и по какой-то причине cls_lasvm::kernel()
не может быть статичным, вам нужно найти способ спрятать указатель this
где-нибудь и извлечь этот указатель в lasvm_kcache_create_callback()
функция, похожая на ту, что я делал в первом примере, за исключением того, что указатель должен исходить из какого-то механизма, который вы сами разработали. Обратите внимание, что это, вероятно, приведет к использованию lasvm_kcache_create()
без повторного входа и без поточного. Это может или не может быть проблемой в зависимости от ваших конкретных обстоятельств.