2016-05-13 7 views
6

Powiedzmy mam funkcję:Funkcja połączenia zna tylko typy parametrów w czasie wykonywania w C?

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

Jedną z cech Chcę zaimplementować jest możliwość, aby użytkownik mógł wywołać dowolną funkcję w sprawie stosowania przez terminal Linux. Więc jako wejście dla oprogramowania, w terminalu wpisać oni coś takiego:

foo 2 'a'

Wtedy moja aplikacja analizuje to, i za pomocą tabel symboli jest w stanie znaleźć adres do foo(), jak również wpisz dla wszystkich swoich parametrów.

Jednak nie jestem pewien, w jaki sposób przekazałbym parametry do funkcji podczas wywoływania, ponieważ mogę mieć setki różnych kombinacji typów parametrów w zależności od funkcji zwanej.

Jakąkolwiek wskazówkę, jak można to osiągnąć bez setek zagnieżdżonych instrukcji if, aby oddać parametry do odpowiednich typów przed wywołaniem funkcji?

Ta funkcjonalność jest podobna do funkcji GDB, w której można wykonać call foo(2,'a') i wywołania GDB, które działają.

+1

Chcesz zbudować własnego interpretera języka C? Zacznijmy od nauki gramatyk formalnych, automatów stanów, lexerów, analizatorów składni i AST. – Drop

+1

Będziesz chciał przeprowadzić pewne sprawdzanie typu, więc jeśli użytkownik napisze 'foo 'a' 2', możesz uniknąć wywołania funkcji z niepoprawnymi argumentami (co prawdopodobnie spowodowałoby awarię twojego programu). Co oznacza, że ​​potrzebujesz sposobu reprezentowania typów wartości w czasie wykonywania i metadane opisujące typy, których oczekuje funkcja, i kod do porównywania tych wartości z innymi. I w tym momencie w zasadzie implementujesz interpreter języka [dynamicznie wpisanego] (https://en.wikipedia.org/w/index.php?title=Dynamic_typing). Rozważ użycie * istniejącego * dynamicznie pisanego języka, takiego jak Python. – Wyzard

+1

@Drop To pytanie nie ma nic wspólnego z interpretacją C. Chodzi o wywoływanie skompilowanych funkcji używających konwencji wywoływania C. –

Odpowiedz

3

Istnieją dwa podejścia do tego. Jeśli to, co opisane jest wszystko, co chcesz zrobić, a następnie można użyć dyncall library tak, że nie trzeba się martwić o Platform/kompilatora specyficzne zawijających semantyki siebie:

Biblioteka dyncall obudowuje architecture-, a Ja- specyficzny dla kompilatora semantyka funkcji połączenia w parametrze wirtualnego argumentu wiązania od lewej do prawej, a następnie interfejs wywołania pozwalający programistom wywoływać funkcje C w całkowicie dynamiczny sposób. Innymi słowy, zamiast wywoływania funkcji bezpośrednio, biblioteka dyncall udostępnia mechanizm do ręcznego przekazywania parametrów funkcji i do wywoływania połączenia.

Innym podejściem jest, jeśli chcesz zrobić więcej: np. co, jeśli argument nie może być utworzony przez literał? Co jeśli argument jest wynikiem innej funkcji? Czy możesz napisać f(123, g("a")) w konsoli? Czy możesz napisać x=g("a"); f(x)? I if(cond) x="a" else x="b"; f(x) W tym przypadku musisz osadzić język skryptowy, np. LUA.

0

Jeśli skompilujesz plik binarny z informacjami debugowania, możesz wyodrębnić go za pomocą libdwarf (https://www.prevanders.net/dwarf.html), więc dla każdej funkcji możesz uzyskać listę parametrów z typami i będziesz wiedział, jak interpretować dane wejściowe użytkownika.

+0

Już jestem w stanie odzyskać te informacje, problem jest bardziej związany z tym, jak wywołać funkcję po poznaniu jej parametrów i ich typów. –

Powiązane problemy