2011-02-28 3 views
5

Je reçois cette question de ce blog chinois http://chenyufei.info/blog/2011-02-28/wrap-c-function-closure-gcc-nested-function/ L'auteur veut utiliser la fermeture en langage c, et il a trouvé que GCC a la capacité de fonction imbriquée (et de fermeture). Par exemple:À propos de wrap et appeler la fonction C

typedef int (*func_t)(int arg); 


int foo(int a) { 

    return a + 1; 

} 


func_t create_wrap_function(func_t f) { 

    int wrapped(int arg) { 

     // call original function 

     int val = f(arg); 

     fprintf(log_func_call, "arg: %d ret: %d", arg, val); 

     return val; 
    } 

    return wrapped; 
} 

Mais ce n'est pas une solution commune. La fonction create_wrap_function a un format de fonction fixe, car func_t limite le format.

Comme nous le savons, Lua a la fermeture, et pourrait appeler la fonction C aussi. Ce que je veux implémenter comme: Les fonctions que nous voulons appeler sont foo1 et foo2, ils ont différents types d'arguments et de valeur de retour.

int foo1(int a) { 
    ... 
    return intValue; 
} 

double foo2(char* str, double a) { 
    ... 
    return dblValue; 
} 

Dans le client C, appelez la fonction comme:

lua_returnValue returnValue1 = Do_Lua_Wrap(__FILE__, __LINE__, foo1, 1); 
lua_returnValue returnValue2 = Do_Lua_Wrap(__FILE__, __LINE__, foo2, "string data", 1.2345); 

Dans le Do_Lua_Wrap, il passera le foo1 et 1 à la fonction Lua, puis appelez foo1 fonction comme processus normal. Passez ensuite le foo2 et un caractère * et une valeur double à la fonction Lua, puis appelez la fonction foo2 comme un processus normal. Dans la fonction Lua, il pourrait enregistrer les informations sur FICHIER et LIGNE et écrire un journal supplémentaire sur les arguments de fonction.

Mais je ne sais pas comment écrire la fonction Do_Lua_Wrap en C et Lua, Est-ce possible?

Si possible, pourriez-vous me donner quelques conseils?

Répondre

2

Vous êtes évidemment intéressé par un variadic function, mais le problème est de déterminer le type des arguments pour pousser sur la pile Lua. Je recommande une approche couple:

  1. La première serait d'inclure une chaîne de format a la les Formats d'emballage de la famille ou binaire printf souvent utilisés dans les langues plus haut niveau . Par exemple, jetez un oeil au format de format utilisé dans le module Lua lpack. La clé est de parcourons la chaîne de format pour déterminer combien et quel type de arguments sont fournis. Vous pouvez également implémenter un type variant. Chaque argument devrait être enveloppé dans une telle structure . En outre, le nombre total d'arguments doit être fourni en tant que premier paramètre. Enfin, vous pouvez passer des arguments dans deux tableaux au lieu d'utiliser une fonction variée . Le premier tableau serait contenir les types énumérés correspondant à la cible de void * pointeurs dans le second tableau. Cette méthode nécessite le plus de code en gardant le code client, mais est assez propre.Un argument spécifiant la longueur des tableaux ou une valeur sentinelle à la fin d'un ou des deux tableaux serait également requis.

Espérons que l'une de ces méthodes devrait fonctionner pour vous. Personnellement, je voudrais aller avec la première option et utiliser le code lpack comme guide. Il s'agit de la plus proche de la signature de la fonction spécifiée dans votre question.

+0

Vous répondez génial! – sagasw

Questions connexes