Я думал, что смогу попробовать более или менее построить объект с нуля без использования блоков impl
. Выработать:Есть ли способ определить смещения каждого из методов trait в VTable?
trait SomeTrait {
fn fn_1(&self);
fn fn_2(&self, a: i64);
fn fn_3(&self, a: i64, b: i64);
}
struct TraitObject {
data: *mut(),
vtable: *mut(),
}
fn dtor(this: *mut()) {
// ...
}
fn imp_1(this: *mut()) {
// ...
}
fn imp_2(this: *mut(), a: i64) {
// ...
}
fn imp_3(this: *mut(), a: i64, b: i64) {
// ...
}
fn main() {
let data = &... as *mut(); // something to be the object
let vtable = [dtor as *mut(),
8 as *mut(),
8 as *mut(),
imp_1 as *mut(),
imp_2 as *mut(),
imp_3 as *mut()]; // ignore any errors in typecasting,
//this is not what I am worried about getting right
let to = TraitObject {
data: data,
vtable: vtable.as_ptr() as *mut(),
};
// again, ignore any typecast errors,
let obj: &SomeTrait = unsafe { mem::transmute(to) };
// ...
obj.fn_1();
obj.fn_2(123);
obj.fn_3(123, 456);
}
Из того, что я понимаю, порядок, в котором функция членов появляется в определении признака не всегда совпадает с функцией указатели появляются в виртуальных таблицах. Есть ли способ определить смещения каждого из методов trait в VTable?
Это подход, который я изначально попытался использовать. Знаете ли вы, можно ли определить смещения функций по имени? Поэтому я мог теоретически переопределить функции во время выполнения? то есть 'override (object, :: fn_1, impl_1)'? –
Я не думаю, что это возможно. В C++ я думаю, что вы можете сделать это с помощью указателей на функции, но у Rust нет таких. –
Черт. Ну, я думал, что, по крайней мере, буду видеть, как далеко я могу продвигать границы с TraitObjects и Dynamic Dispatch. Это довольно неплохое начало. –