2009-09-11 8 views
1

J'ai cette signature de la fonction que je dois correspondreAide bind boost/fonctions

typedef int (*lua_CFunction) (lua_State *L);//target sig 

Voici ce que j'ai jusqu'à présent:

//somewhere else... 
    ... 
registerFunction<LuaEngine>("testFunc", &LuaEngine::testFunc, this); 
    ... 

    //0 arg callback 
void funcCallback0(boost::function<void()> func, lua_State *state) 
{ 
    func(); 
} 

template<typename SelfType> 
void registerFunction(const std::string &funcName, boost::function<void (SelfType*)> func, SelfType *self) 
{ 
      //funcToCall has to match lua_CFunction 
    boost::function<void (lua_State *)> funcToCall = boost::bind(&LuaEngine::funcCallback0, this, 
     boost::bind(func, self), _1); 
    lua_register(_luaState, funcName.c_str(), funcToCall); 
} 

Cependant, à lua_register(_luaState..., il se plaint encore de problèmes de conversion

erreur 1 erreur C2664: 'lua_pushcclosure': ne peut pas convertir paramètre 2 de 'boost :: fonction' à 'lua_CFunction'

Quelqu'un sait comment cela peut être résolu?

+0

Une question plus large qui touche le même problème général de conversion de 'boost :: function' en pointeurs C simples: http://stackoverflow.com/questions/282372/demote-boostfunction-to-a-plain-function- pointeur –

Répondre

4

Cela ne peut pas être résolu directement. Lua API veut que vous utilisiez des pointeurs de fonctions simples - c'est juste un pointeur de code, et rien d'autre. Pendant ce temps, boost::function est un objet fonction, et il n'est pas possible qu'il soit convertible en un pointeur de fonction, parce que - grosso modo - il capture non seulement le code, mais aussi l'état. Dans votre exemple, l'état capturé est la valeur self. Il a donc un pointeur de code pour le code, et quelques données - et l'API cible attend seulement le pointeur de code.

+0

Veuillez lire la réponse que je viens de poster. Ma suspicion originale était similaire à la vôtre (en ce sens qu'un func ptr ne peut pas capturer l'état), mais il s'avère que cela peut passer par une belle magie. – jameszhao00

+0

Non, vous avez tort. À partir des docs Boost (http://www.boost.org/doc/libs/1_37_0/doc/html/boost/function_base.html#id2623958-bb): «' template Functor * target(); ' - Si cela stocke une cible de type Functor, renvoie l'adresse de la cible, sinon, renvoie le pointeur NULL. " - et dans votre cas, le résultat de 'bind' ne stockera pas la cible de type' lua_CFunction'. Il n'y a pas de magie là-bas (enfin, il n'y a pas de magie en général). Il n'est pas possible de presser 8 octets au hasard dans 4. –

+0

Voir aussi http://lists.boost.org/Archives/boost/2008/12/145709.php –

1

Le problème est que le compilateur ne peut pas déduire le paramètre de modèle car il existe une conversion implicite.

Vous devez stocker le pointeur de fonction dans un objet fonction.

function<int(lua_State *)> f = boost::bind(&LuaEngine::testFunc, this) 
registerFunction<LuaEngine>("testFunc", f); 

Et votre fonction attend un type de retour vide et qui est nécessaire pour passer à int aussi.

+0

J'ai changé le type de retour en int. J'ai oublié ça au début. – jameszhao00

+0

Donc vous dites que ce qui précède ne fonctionne pas? Ou ça marche? – jameszhao00

+0

l'exemple que je donne devrait fonctionner. La raison de ne pas travailler est pour votre exemple. Désolé pour la confusion. – leiz