To export a generic Writer to FFI, we can do something like:
#![feature(box_syntax)]
use std::io::{self, Write};
struct BaseWriter {
write: fn(*mut BaseWriter, &[u8]) -> Result<(), io::Error>,
}
struct ImplWriter<A> {
base: BaseWriter,
x: A,
}
impl<A> ImplWriter<A>
where
A: Write,
{
fn vtable(xs: &mut A) -> BaseWriter {
BaseWriter { write: write::<A> }
}
}
fn write<A>(xs: *mut BaseWriter, x: &[u8]) -> Result<(), io::Error>
where
A: Write,
{
unsafe {
let xs = xs as *mut ImplWriter<A>;
(*xs).x.write_all(x)
}
}
#[cfg(test)]
mod tests {
use std::{fs::File, io::Write};
use crate::{BaseWriter, ImplWriter};
#[test]
fn test_main() {
let mut writer = File::create("./test.out").unwrap();
let impl_writer = ImplWriter::vtable(&mut writer);
let mut impl_writer = ImplWriter {
base: impl_writer,
x: writer,
};
let impl_writer: *mut _ = &mut impl_writer;
let impl_writer: *mut BaseWriter = impl_writer as _;
unsafe {
let f = (*impl_writer).write;
f(impl_writer, format!("========\n").as_bytes()).unwrap()
}
}
}
but for then
of futures, this method does not work. Also a boxed trait object can not be send to FFI directly for the Sized
constraints on then
.