You're seeing that error message because `serialize::read_message()` is meant to be called on a `std::io::Read` that contains the raw bytes of a stream-framed <https://capnproto.org/encoding.html#serialization-over-a-stream> Cap'n Proto message. You are instead calling it on a `vm_capnp::input_output::Reader`, which is a typed reference to the interior of a Cap'n Proto message.
It looks like part of your problem is that you are defining `evaluate()` with a signature of `fn(*mut vm_capnp::input_output::Reader) -> ()` and then you are loading it with the incompatible signature of `fn(vm_capnp::input_output::Reader) -> vm_capnp::input_output::Reader`. What is the goal of exporting this function through the C ABI? Is it intended that non-Rust code will call it? If so, how will such code get a handle on a `vm_capnp::input_output::Reader` in the first place? On Fri, Apr 14, 2017 at 4:25 AM, stewart mackenzie <[email protected]> wrote: > Greetings, > > I have a executable binary and a shared object (implemented in rust) with > a C ABI. > > I'm passing a capnp message from the binary through the C ABI. > > This is what the schema looks like: > > @0xc98fff04bdc3a38a; > struct Input { > gas @0 :Int32; > code @1 :List(Data); > data @2 :List(Data); > } > struct Output { > gas @0 :Int32; > code @1 :List(Data); > } > struct InputOutput { > input @0 :Input; > output @1 :Output; > } > > this is the executable binary > > > fn evaluate(msg: vm_capnp::input_output::Reader) -> libloading::Result > <vm_capnp::input_output::Reader> { let lib = libloading::Library::new(" > libsputnikvm.so").expect("cannot load"); > unsafe { > let func: libloading::Symbol<unsafe extern fn(vm_capnp::input_output::Reader) > -> vm_capnp::input_output::Reader> = try!(lib.get(b"evaluate")); > Ok(func(msg)) > } > } > > this is what the C ABI shared object receiving code looks like: > > use vm_capnp::input_output::Reader; > #[no_mangle] > pub extern fn evaluate(ptr: *mut Reader) { > let msg = unsafe { > assert!(!ptr.is_null()); > &mut *ptr > }; > > let io_reader = serialize::read_message(&mut msg, > message::ReaderOptions::new()).expect("read message failed."); let io = > io_reader.get_root::<Reader>().expect("Failed to get VM IO."); > println!("{}", io.get_input().expect("FAILED").get_gas()); > } > > > The error message is this: > > error[E0277]: the trait bound `vm_capnp::input_output::Reader<'_>: > std::io::Read` is not satisfied > --> src/lib.rs:31:21 > | > 31 | let io_reader = serialize::read_message(&mut msg, > message::ReaderOptions::new()).expect("read message failed."); > | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::io::Read` > is not implemented for `vm_capnp::input_output::Reader<'_>` > | > = note: required because of the requirements on the impl of > `std::io::Read` for `&mut vm_capnp::input_output::Reader<'_>` > = note: required by `capnp::serialize::read_message` > > I would really like to deserialize correctly, I'm doing something very > wrong. I know it's something small I'm missing. > > You can reproduce by doing this: > > git clone github.com/sjmackenzie/sputnikvm > cd sputnikvm > capnp eval --binary tests/mod.capnp all > tests.bin && RUST_BACKTRACE=full > cargo run --bin gaslighter -- -t tests.bin -k -r // > > The relevant lines of code for the binary (https://github.com/ > sjmackenzie/sputnikvm/blob/dev/src/bin/gaslighter/mod.rs#L88) > for the receiving shared object library (https://github.com/ > sjmackenzie/sputnikvm/blob/dev/src/lib.rs#L25) > > Thanks in advance > kr/sjm > > -- > You received this message because you are subscribed to the Google Groups > "Cap'n Proto" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > Visit this group at https://groups.google.com/group/capnproto. > -- You received this message because you are subscribed to the Google Groups "Cap'n Proto" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. Visit this group at https://groups.google.com/group/capnproto.
