2016-05-13 24 views
6

Diciamo che ho una funzione:La funzione di chiamata conosce solo i tipi di parametri in fase di esecuzione in C?

int foo (int A, char B){...} 

Una delle caratteristiche che voglio implementare è la capacità per l'utente di chiamare qualsiasi funzione sull'applicazione attraverso il terminale di Linux. Così come input per il software, nel terminale si digita qualcosa del tipo:

foo 2 'a'

Poi la mia applicazione analizza questo, e utilizzando le tabelle dei simboli è in grado di trovare l'indirizzo per foo(), così come il digitare per tutti i suoi parametri.

Tuttavia, non sono sicuro di come passare i parametri alla funzione durante la chiamata, poiché posso avere centinaia di tipi di parametri diversi in base alla funzione chiamata.

Qualche suggerimento su come si potrebbe ottenere senza avere centinaia di istruzioni nidificate if per trasmettere i parametri ai tipi corretti prima di chiamare le funzioni?

Questa funzionalità è simile a quella di GDB, dove è possibile effettuare chiamate call foo(2,'a') e GDB a tale funzione.

+1

Quindi vuoi costruire il tuo interprete C? Bene, inizia con l'apprendimento di grammatiche formali, macchine di stato, lexer, parser e AST. – Drop

+1

Dovrai fare un controllo di tipo, in modo che se l'utente scrive 'foo 'a' 2' puoi evitare di chiamare la funzione con argomenti non validi (il che probabilmente causerebbe il crash del tuo programma). Ciò significa che è necessario un modo per rappresentare i tipi di valori in fase di esecuzione e metadati che descrivono i tipi che la funzione si aspetta e il codice per confrontare l'uno con l'altro. E a quel punto stai praticamente implementando un interprete per un linguaggio [dinamicamente tipizzato] (https://en.wikipedia.org/w/index.php?title=Dynamic_typing). Prendi in considerazione l'uso di un * linguaggio * esistente dinamicamente tipizzato, come Python. – Wyzard

+1

@Drop Questa domanda non ha nulla a che fare con l'interpretazione di C. Si tratta di chiamare funzioni compilate che usano la convenzione di chiamata C. –

risposta

3

Ci sono due approcci a questo. Se quello che hai descritto è tutto quello che vuole fare, quindi è possibile utilizzare il dyncall library in modo che non si deve preoccupare di piattaforma/specifiche del compilatore chiamata semantica te:

La biblioteca dyncall incapsula architecture-, sistema operativo e semantica chiamata di funzione specifica del compilatore in un parametro di argomento bind virtuale da sinistra a destra e quindi chiamata all'interfaccia che consente ai programmatori di chiamare le funzioni C in modo completamente dinamico. In altre parole, invece di chiamare direttamente una funzione, la libreria dyncall fornisce un meccanismo per spingere i parametri della funzione manualmente e per emettere la chiamata in seguito.

L'altro approccio è, se si potrebbe voler fare di più: ad es. cosa succede se un argomento non può essere creato da un letterale? Cosa succede se l'argomento è l'output di un'altra funzione? Puoi scrivere f(123, g("a")) nella tua console? Sai scrivere x=g("a"); f(x)? E if(cond) x="a" else x="b"; f(x) In questo caso è necessario incorporare un linguaggio di scripting come ad es. LUA.

0

Se si compila il proprio binario con informazioni di debug, è possibile estrarlo utilizzando libdwarf (https://www.prevanders.net/dwarf.html), quindi per ogni funzione è possibile ottenere un elenco con parametri e si dovrebbe sapere come interpretare l'input dell'utente.

+0

Sono già in grado di recuperare tali informazioni, il problema è più correlato a come chiamare la funzione dopo averne conoscuto i parametri e i tipi. –

Problemi correlati