Код ржавчины:
#[repr(C)]
pub struct Tmp {
pub callback: extern "C" fn(i: i32),
}
#[no_mangle]
pub extern "C" fn set_callback(callback: extern "C" fn(i: i32)) -> *mut Tmp {
let mut tmp = Box::new(Tmp { callback });
println!("tmp as ptr: {:p}", tmp); // >> here <<
&mut *tmp
}
#[no_mangle]
pub extern "C" fn use_callback(tmp_ptr: *mut Tmp) {
unsafe {
((*tmp_ptr).callback)(1);
((*tmp_ptr).callback)(3);
}
}
C ++ код:
struct Tmp {
void (*callback)(int32_t);
};
typedef Tmp*(__stdcall* set_callback_t)(void(*callback_t)(int32_t));
typedef void(__stdcall* use_callback_t)(Tmp*);
void callback(int32_t i) {
printf("%d\n", i * 2);
}
int main() {
// ... loading rust part as .dll
// ... checking if loaded correctly
Tmp* tmp_ptr = set_callback(callback);
printf("tmp_ptr %p\n", tmp_ptr);
use_callback(tmp_ptr);
// ... freeing the .dll
}
Когда я компилирую эту программу, она работает как положено. Напечатанные значения указателя на структуру Tmp
в Rust и C ++ совпадают. Когда я комментирую println
в Rust, происходит сбой программы на C ++, что означает, что с этим (возможно, частью Rust) что-то не так.
Я использую код Rust в качестве .dll. Я хотел бы передать указатель на функцию C ++ в функцию set_callback
, а затем я бы хотел использовать этот указатель в функции use_callback
при вызове use_callback
в коде C ++.
Насколько я понимаю, в конце мне придется вызвать функцию Rust, чтобы отбросить структуру Tmp
, но я пропустил это.