Je suppose que l'argument est closure
un contexte 'cookie' pour l'utilisation du rappel pour obtenir le contexte approprié. Ceci est un idiot d'acomon pour les fonctions de rappel, et semble être ce qui se passe sur la base des extraits que vous avez fournis (mais je ne sais pas avec certitude, car je ne sais rien sur kcache_create()
sauf ce que vous avez posté ici).
Vous pouvez utiliser ce cookie pour passer un pointeur vers le vous par exemple cls_lasvm
traiter comme ceci:
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);
Si je me trompe fermeture étant un cookie contexte, votre fonction de rappel dans la cls_lasvm
classe doit être statique:
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);
Notez qu'une fonction de rappel C implémenté en C++ doit êtreextern "C"
. Cela peut sembler fonctionner comme une fonction statique dans une classe car les fonctions de classe-statique utilisent souvent la même convention d'appel qu'une fonction C. Cependant, faire cela est un bug qui attend de se produire (voir les commentaires ci-dessous), donc s'il vous plaît ne faites pas - passer par un wrapper extern "C"
à la place.
Si closure
n'est pas un cookie de contexte et pour une raison quelconque cls_lasvm::kernel()
ne peut pas être statique alors vous devez trouver un moyen de cacher un pointeur this
quelque part et récupérer ce pointeur dans la fonction lasvm_kcache_create_callback()
, semblable à la façon Je l'ai fait dans mon premier exemple, sauf que le pointeur doit provenir d'un mécanisme que vous vous imaginez. Notez que cela va probablement utiliser lasvm_kcache_create()
non-réentrant et non-threadsafe. Cela peut ou peut ne pas être un problème en fonction de vos circonstances spécifiques.
Je ne pense pas qu'il y ait un "premier paramètre" caché implicite: vous pourriez tout aussi bien dire qu'il a un "dernier paramètre" caché implicite. La valeur 'this' est disponible dans l'appelé, c'est tout. Donc ce n'est pas "vraiment" ce que vous avez dit - essayez de changer 'kernelfunc' pour ce type, et le code ne compilera toujours pas. pointer-to-function et pointer-to-member-function sont des choses différentes. –
@Steve: Je pense qu'il est généralement défini comme le premier paramètre, en fait. Cette distinction fait la différence, puisque d'autres fonctions (et d'autres langages, je suppose) ont besoin de savoir dans quel ordre passer ces paramètres. –
__Ne pas utiliser la méthode des membres statiques pour les méthodes de rappel C. Il n'est pas garanti de fonctionner car la norme C++ ne spécifie pas délibérément un ABI. –