У меня есть код C++, который вызывает код Rust с данными. Он знает, на какой объект отправлять данные. Вот пример функции Rust, которую C++ вызывает обратно:
extern "C" fn on_open_vpn_receive(
instance: Box<OpenVpn>,
data: *mut c_uchar,
size: *mut size_t,
) -> u8
Он получает указатель как Box
, поэтому я создал функцию openvpn_set_rust_parent
, которая устанавливает, какой объект C++ должен вызывать обратно. Этот объект является указателем на самого себя. Я использую Pin
, поэтому Box
не перераспределяется куда-то еще, из-за чего С++ вызывает недопустимый адрес.
impl OpenVpn {
pub fn new() -> Pin<Box<OpenVpn>> {
let instance = unsafe { interface::openvpn_new(profile.as_ptr()) };
let o = OpenVpn { instance: instance };
let p = Box::pin(o);
unsafe {
interface::openvpn_set_rust_parent(o.instance, p.as_ptr());
};
p
}
}
Подпись:
pub fn openvpn_set_rust_parent(instance: *mut OpenVpnInstance, parent: *mut OpenVpn)
Я не знаю, как преобразовать p
в *mut OpenVpn
для перехода на C++. Моя идея в порядке? Я думаю, что использование Pin
здесь хорошо, и я думаю, что это хороший способ вызова объекта из C++.
std::boxed
. Так что не пишите эту подпись в первую очередь. - person Sebastian Redl   schedule 11.11.2020Box
— это крайне подозрительно, так как это означает, что функция должна быть вызвана один раз и ровно один раз. Если это вызывается ноль раз, у вас есть утечка памяти. Если он вызывается дважды, вы будете использовать память после ее освобождения. Учитывая, что вы возвращаетеp
из функции, это означает, что как только сработает обратный вызов, любой код Rust, обращающийся кp
, вызовет неопределенное поведение. То же самое, еслиp
отбрасывается кодом Rust до того, как произойдет обратный вызов. - person Shepmaster   schedule 14.11.2020OpenVpn
, поэтому код C выглядит так, как будто он принадлежитOpenVpn
.openvpn_set_rust_parent
просто устанавливает обратный вызов внутри класса C++, чтобы он знал, какой объект (его родитель) вызывать. Вызов дважды или более просто устанавливает обратный вызов снова. Также нет никакого способа ничего не вызывать, потому что он вызывает своего родителя, который всегда живет больше, чем он. Итак, учитывая эти факты, я думаю, имеет смысл вызыватьopenvpn_set_rust_parent
и при этом возвращатьp
. Что вы думаете? - person Guerlando OCs   schedule 14.11.2020