2011-02-28 10 views
5

Ricevo questa domanda da questo blog cinese http://chenyufei.info/blog/2011-02-28/wrap-c-function-closure-gcc-nested-function/ L'autore desidera utilizzare la chiusura in linguaggio c, e ha trovato che GCC ha la capacità di funzione annidata (e chiusura). Per esempio:Informazioni su avvolgere e chiamare la funzione 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; 
} 

Ma non è soluzione comune. create_wrap_function ha un formato di funzione fisso, poiché func_t limita il formato.

Come sappiamo, Lua ha chiuso e potrebbe chiamare anche la funzione C. Cosa voglio implementare come: Le funzioni che vogliamo chiamare sono foo1 e foo2, hanno diversi tipi di argomenti e valore restituito.

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

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

In C client, chiamare la funzione come:

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

Nel Do_Lua_Wrap, passerà la foo1 e 1 alla funzione Lua, quindi chiamare foo1 funzione come il processo normale. Quindi passare il foo2 e un char * e un doppio valore alla funzione Lua, quindi chiamare la funzione foo2 come un processo normale. Nella funzione Lua, è possibile registrare le informazioni su FILE e LINE e scrivere un registro aggiuntivo sugli argomenti delle funzioni.

Ma non ho idea di come scrivere la funzione Do_Lua_Wrap in C e Lua, È possibile?

Se possibile, potrebbe darmi dei consigli?

risposta

2

Si è ovviamente interessati a un variadic function, ma il problema è determinare il tipo di argomenti da inserire nello stack Lua. Io consiglio un paio di approcci:

  1. Il primo sarebbe quello di includere una stringa di formato a la i printf famiglia o l'imballaggio binario formati spesso utilizzati nel livello più alto lingue. Ad esempio, dai uno sguardo allo con il modello di formato utilizzato nel modulo lpack Lua. La chiave è per la scansione attraverso la stringa di formato su determinare quanti e quali tipi di argomenti vengono forniti.

  2. In alternativa, è possibile implementare un tipo variant. Ogni argomento dovrebbe essere incluso in una tale struttura . Inoltre, il numero totale di argomenti deve essere fornito come come primo parametro.

  3. Infine, è possibile passare argomenti in due matrici invece di utilizzare una funzione variadica . La prima matrice contiene i tipi enumerati corrispondenti alla destinazione dei puntatori void * nella seconda matrice. Questo metodo richiede la maggior parte della casa mantenendo il codice cliente, ma è abbastanza pulito.Sarebbe anche richiesto un argomento che specifichi la lunghezza degli array o un valore sentinella alla fine di uno o entrambi gli array.

Eventualmente, uno di questi metodi dovrebbe funzionare per voi. Personalmente, vorrei andare con la prima opzione e utilizzare il codice lpack come guida. Si avvicina di più alla firma della funzione specificata nella tua domanda.

+0

La tua risposta è fantastica! – sagasw

Problemi correlati