2015-08-31 13 views
5

Jak uzyskać adres funkcji w Rust? Co dokładnie oznacza "&"?Jak uzyskać adres funkcji?

jaki adres mogę dostać robi

std::mem::transmute::<_, u32>(function) 

lub

std::mem::transmute::<_, u32>(&function) 

(w systemie 32-bitowym, oczywiście)?

Co

&function as *const _ as *const c_void 

dać?

UPD. Odpowiedź @Shepmaster poniżej daje odpowiedź na to pytanie (choć podaje też inne nieistotne, ale może być przydatne dla niektórych informacji). Podsumuję to tutaj.

Uzyskanie adresu jest proste, wystarczy

funct as *const() 

odniesienia do funkcji wydaje się utworzenie zmiennej lokalnej podobnie jak z

let a = &42; 
+1

Czy jesteś zaznajomiony z Rust Playground [] (https://play.rust-lang.org /)? Pozwoli ci to odpowiedzieć na pytania typu "jaki wynik ma ten kod". – Shepmaster

+1

Jeśli chcesz przechowywać wskaźnik w całości, użyj 'usize' zamiast' u32' lub 'u64', to gwarantuje, że ma taki sam rozmiar jak wskaźnik. –

+0

@Shepmaster: Wiem jaki jest wynik tego kodu (I kbow jak uruchamiać programy rdzy, tak ;-)), pytanie dotyczy tego, jakie dokładnie adresy dostaję, a odpowiedź poniżej rzuca światło na to. –

Odpowiedz

6

Gdybym tylko chciał znać adres funkcji, ja Prawdopodobnie po prostu wypisz go:

fn moo() {} 

fn main() { 
    println!("{:p}", moo as *const()); 
} 

Jednak nie mogę wymyślić przydatnego reaso n chcesz to zrobić. Zwykle jest coś, co chcesz do z funkcją. W tych przypadkach, równie dobrze można po prostu przekazać funkcję bezpośrednio, bez potrzeby zajmowania się adresem:

fn moo() {} 

fn do_moo(f: fn()) { 
    f() 
} 

fn main() { 
    do_moo(moo); 
} 

jestem mniej pewny na ten temat, ale myślę, że std::mem::transmute::<_, u32>(&function) byłoby wystarczy utworzyć lokalną zmienną że punkty do function, a następnie otrzymuje odniesienie do tej zmiennej. To pasuje jak ten kod działa:

fn main() { 
    let a = &42; 
} 

nie muszę pracować z nimi w Rust, muszę adres, bo mam trochę FFI, która pobiera adres symbolu w bieżącym procesie

można jeszcze po prostu przekazać funkcję jak jest do extern funkcji, które będą korzystać z callback:

extern { 
    fn a_thing_that_does_a_callback(callback: extern fn(u8) -> bool); 
} 

extern fn zero(a: u8) -> bool { a == 0 } 

fn main() { 
    unsafe { a_thing_that_does_a_callback(zero); } 
} 
+0

Wygląda na to, że masz rację co do referencji, dzięki. Wiem, jak pracować z funkcjami.Ale nie muszę pracować z nimi w Rust, potrzebuję adresu, ponieważ mam trochę FFI, który bierze adres symbolu w bieżącym procesie (tak, moja funkcja jest oznaczona jako extern, więc ma właściwe konwencje wywoływania). –

+0

> Nadal można po prostu przekazać funkcję tak jak jest do zewnętrznych funkcji, które będą używać wywołania zwrotnego. Nie, nie mogę. Funkcja zewnętrzna akceptuje adresy. Kropka. Ale twoje komentarze (z println!) Pomogły, dzięki. Użyłem go w tych zatwierdzeniach: https://github.com/jauhien/iron-kaleidoscope/commit/154136f732f685eb6ab206e26c1f79a91de2f8b2 i https://github.com/jauhien/iron-llvm/commit/eae180417912eeade7c35b16a12bdce69ebfaf84 –