Rust代码:
#[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
}
当我编译这个程序时,它按预期工作。 Rust和C ++中指向Tmp
结构的指针的打印值匹配。当我在Rust中注释掉println
时,C ++程序崩溃了,这意味着这个(可能是Rust部分)代码有问题。
我使用Rust代码作为.dll。我想将一个指向C ++函数的指针传递给set_callback
函数,然后当我在C ++代码中调用use_callback
时,我想在use_callback
函数中使用该指针。 / p>
根据我的理解,最后我将不得不调用Rust函数来删除Tmp
结构,但我把它留了出来。
答案 0 :(得分:5)
Box
与C ++中的std::unique_ptr
类似。构造tmp
的方式,指向的数据将在函数末尾释放。
为了将指针“泄漏”到C ++世界,你应该使用Box::into_raw
。
请注意,由于无法保证Rust和C ++以相同的方式分配内存;你必须将指针传递回Rust并使用Box::from_raw
来解除分配。