Zobacz the answer I just posted na to pytanie. Możesz użyć biblioteki callback(3)
, aby wygenerować nowe funkcje w środowisku wykonawczym. Nie jest to zgodne ze standardami, ponieważ zawiera wiele brzydkich, specyficznych dla platformy hacków, ale działa na wielu systemach.
Biblioteka zajmuje się przydzielaniem pamięci, upewniając się, że pamięć jest wykonywalna i czyści pamięć podręczną instrukcji, jeśli jest to konieczne, w celu zapewnienia, że kod, który jest generowany dynamicznie (tj. Zamknięcie), jest wykonywalny. Zasadniczo generuje kody kodu, które mogą wyglądać tak na x86:
pop %ecx
push $THUNK
push %ecx
jmp $function
THUNK:
.long $parameter
Następnie zwraca adres pierwszej instrukcji. To, co robi ten kod pośredniczący, zapisuje adres powrotu do ECX (rejestru zdrapek w konwencji wywoływania x86), przesuwa dodatkowy parametr na stos (wskaźnik do thunk), a następnie ponownie przesyła adres zwrotny. Następnie przechodzi do rzeczywistej funkcji. Powoduje to, że funkcja zaczyna się oszukiwać, myśląc, że ma dodatkowy parametr, który jest ukrytym kontekstem zamknięcia.
Jest to faktycznie bardziej skomplikowane (rzeczywistą funkcją wywoływaną na końcu kodu pośredniczącego jest __vacall_r
, a nie sama funkcja, a __vacall_r()
obsługuje więcej szczegółów implementacji), ale to jest podstawowa zasada.
Nie sądzę, że konieczne jest podanie linku do strony głównej stackoverflow.com w pytaniu. –
Pytanie, które łączysz, dotyczy tego, jak to zrobić w C++. To pytanie jest oznaczone C. Którego chcesz się dowiedzieć? –
Rozwiązanie przedstawione przez Barry znajduje się w C. Większość komentarzy sugeruje, że nie jest możliwe rozwiązanie mojego pierwszego pytania w C++. – Alexandru