This crate provides macros to generate C++-ABI VTables by defining the structure and vtable layout. It also supports VTable inheritance and basic class inheritance.
Check out tests.rs
, which is pretty self-explanatory.
VTable
exactly. Example:
rs
struct Foo {}
struct FooVTable {}
#[gen_vtable]
. Any function pointers you include in
the VTable struct will require implementation in an automatically-generated <name>Virtuals
trait.
Complete Example:
```rs
struct Foo {}
struct FooVTable { foo: extern "C" fn(this: &Foo) -> u32; } impl FooVirtuals for Foo { extern "C" fn foo(this: &Foo) -> u32 { todo!() } } ```
base
. Example:
```rs
struct Foo {}
struct FooVTable {}
struct Bar {}
struct BarVTable {} ```
Constructing structs with VTables is easy. If the struct is default-able, simply derive
DefaultVTable
instead of Default
. This will impl Default
. If the struct isn't default-able,
define some function fn new(/* args */) -> Self
. Mark the function with new_with_vtable
,
supplying base structs if necessary as in Derived Structs
. For the compiler to know the type,
you must either explicitly replace Self
as the return type with the type itself, or specify
self_type
. Here's a verbose example:
rs
// ...
impl Bar {
#[new_with_vtable(self_type = "Bar")]
fn new(baz: u32) -> Self {
Self { baz }
}
}
which is also equivalent to
rs
// ...
impl Bar {
#[new_with_vtable]
fn new(baz: u32) -> Bar {
Self { baz }
}
}
If there is a base struct that requires its new
function to be called, you will have to also
explicitly initialize a base_with_vtbl
member with the new
constructor of the child type.
For example:
rs
// ...
impl Bar {
#[new_with_vtable(base = "Foo", self_type = "Bar")]
fn new(baz: u32) -> Self {
Self {
base_with_vtable: Foo::new(123),
baz
}
}
}
Overriding functions is easy. Because all functions are defined in Traits, one can specify for the
compiler to not generate implementations for base struct Virtuals
with the argument no_base_trait_impl
on the VTable (or both for symmetry :)).
Example:
```rs // ...
struct BarVTable {} // ... impl FooVirtuals for Bar { extern "C" fn some_fn(this: &Foo) { // ... } } ```
The only caveat is you will have to implement all base traits.
vtable_gen
currently does not support generic structs. This is a trivial addition, however, and
will likely be added in the future