messageToFlatArray() involves an extra copy compared to
getSegmentsForOutput().

However, you are putting the bytes into a protobuf anyway. Protobuf will
make many copies. So I don't think you should worry too much about this one
extra copy.

If you really want to use getSegmentsForOutput(), then you need to use a
`repeated bytes` field in protobuf and you need to add each segment to the
repeated bytes.

-Kenton

On Sun, Oct 6, 2019 at 8:00 PM 张小 <[email protected]> wrote:

>  hi Kenton:
>     getSegmentsForOutput() performance better than messageToFlatArray
> right?  These two interfaces  What scenarios are applied to?
>
>   best wish
>   whutbd
>
> 在 2019年10月7日星期一 UTC+8上午3:41:23,Kenton Varda写道:
>>
>> Your code only handles the case of a single segment. I recommend using
>> the methods in capnp/serialize.h and org.capnproto.Serialize. I do not
>> recommend using getSegmentsForOutput() nor constructing a MessageReader
>> directly from a segment array, as these are advanced functions that can
>> more easily go wrong.
>>
>> That said, in your example case, only a single segment should be needed,
>> so something else is wrong too.
>>
>> I don't see any other obvious problems with the code you provided. I
>> suspect a bug exists in the code you didn't show. I recommend you try to
>> verify that the bytes on the receiving end are actually exactly the bytes
>> from the sending end. Try logging the byte values and the size of the
>> segment at each end to make sure everything matches.
>>
>> I think the most likely problem is that somewhere your `char*` is being
>> interpreted as a NUL-terminated string, and is therefore being truncated at
>> the first zero-valued byte. Most likely, the very first byte in the segment
>> is a zero, so probably your ByteBuffer on the Java end ends up being
>> zero-length. This probably leads to the struct appearing to contain only
>> default values, hence goodsId is 0.
>>
>> -Kenton
>>
>> On Sat, Oct 5, 2019 at 11:28 PM 张小 <[email protected]> wrote:
>>
>>> hi Kenton:
>>>   I need your help,This problem has been bothering me for many days.
>>>
>>> In c++ server ,code like this
>>> capnp::MallocMessageBuilder message;
>>> FullInfo::Builder fullInfo = message.initRoot<FullInfo>();
>>> fullInfo.setGoodsId(919731)
>>>
>>> kj::ArrayPtr<const kj::ArrayPtr<const capnp::word>> segments
>>> = message.getSegmentsForOutput();
>>> kj::ArrayPtr<const capnp::word> segment = segments[0];
>>> kj::ArrayPtr<const char> chars = segment.asChars();
>>> const char* mem_buf = chars.begin();
>>> int32_t mem_buf_len = chars.size();
>>>
>>> and c++ server send the mem_buf to java_client by rpc call(bytes field)
>>>
>>> *Client and server communicate through protobuf rpc*
>>>
>>> In java_client code like this:()
>>>
>>> com.google.protobuf.ByteString capn_object_bytes =
>>>  response.getCapnObject();
>>> ByteBuffer[] bytes_buffer = new ByteBuffer[1];
>>> bytes_buffer[0] = capn_object_bytes.asReadOnlyByteBuffer();
>>> MessageReader message = new MessageReader(bytes_buffer,
>>> ReaderOptions.DEFAULT_READER_OPTIONS);
>>> Display.FullInfo.Reader fullInfo  =
>>> message.getRoot(Display.FullInfo.factory);
>>> System.out.println("goodsId:" + fullInfo.getGoodsId());
>>>
>>> but in java_client ,print goodsId is 0, however in c++ server, I
>>> setGoodsId(919731) ,What's wrong with my method of use? @Kenton
>>>
>>> the fullinfo.capnp code is:
>>> @0xcb70f505c89d1634;
>>>
>>> using Java = import "./compiler/src/main/schema/capnp/java.capnp";
>>> $Java.package("org.capnproto.examples");
>>> $Java.outerClassname("Display");
>>>
>>> struct FullInfo{
>>>     goodsId @1 :Int64;
>>>  }
>>>
>>>
>>>
>>>
>>>
>>> 在 2019年10月1日星期二 UTC+8上午3:23:37,Kenton Varda写道:
>>>>
>>>> Are you transmitting one big buffer containing all the segments, or are
>>>> you transmitting each segment separately?
>>>>
>>>> It looks like you're trying to do the latter, but in that case you
>>>> cannot use Serialize.read() to read it. You need to use `new
>>>> MessageReader(segments)`.
>>>>
>>>> -Kenton
>>>>
>>>> On Mon, Sep 30, 2019 at 5:52 AM 张小 <[email protected]> wrote:
>>>>
>>>>> First Time:
>>>>>  In C++ server,I Use capnp::DynamicStruct, code like this:
>>>>> capnp::MallocMessageBuilder msg;
>>>>> capnp::DynamicStruct::Builder fullinfo_builder
>>>>> = msg.initRoot<capnp::DynamicStruct>(g_schema);
>>>>> capnp::DynamicStruct::Builder fullInfo =
>>>>> msg.initRoot<capnp::DynamicStruct>(g_schema);
>>>>>
>>>>> capnp::messageToFlatArray(msg);  ---->convert it to char* send to
>>>>> java_cliet
>>>>>
>>>>> Java Client ,code like this:
>>>>> MessageReader message
>>>>> = org.capnproto.Serialize.read(capn_object_bytes.asReadOnlyByteBuffer());,
>>>>> Info.Reader adInfo = message.getRoot(Info.factory);
>>>>>
>>>>> Above , My First Time do work , but The Second Time, I do like this
>>>>> ,it do not work:
>>>>>  In C++ server, code like this:
>>>>>
>>>>> capnp::MallocMessageBuilder message;
>>>>> Info::Builder info = message.initRoot<Info>();
>>>>> info.setId(123);
>>>>> kj::ArrayPtr<const kj::ArrayPtr<const capnp::word>> segments =
>>>>> message.getSegmentsForOutput();
>>>>>
>>>>> then I convert the  segments  object to char* send to java_client by
>>>>> proto rpc_call (bytes field)
>>>>>
>>>>>
>>>>> Java Client ,code like this:
>>>>> MessageReader message
>>>>> = org.capnproto.Serialize.read(capn_object_bytes.asReadOnlyByteBuffer());,
>>>>> Info.Reader adInfo = message.getRoot(Info.factory);
>>>>>
>>>>>
>>>>> In Second Time, happen Error like this:
>>>>>
>>>>> Exception in thread "main" java.lang.IllegalArgumentException
>>>>> at java.nio.Buffer.limit(Buffer.java:275)
>>>>> at org.capnproto.Serialize.read(Serialize.java:140)
>>>>> at org.capnproto.Serialize.read(Serialize.java:111)
>>>>>
>>>>> How Can I do , In Second Time ,thanks
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> 在 2019年9月30日星期一 UTC+8下午8:29:41,David Renshaw写道:
>>>>>>
>>>>>> On the Java side, you need to first read the bytes into a
>>>>>> `MessageReader`. That's typically done via one of the `Serialize.read()`
>>>>>> methods.
>>>>>>
>>>>>> The `AnyPointer.Reader()` is not intended for external use. Probably
>>>>>> we should make it private.
>>>>>>
>>>>>>
>>>>>> On Mon, Sep 30, 2019 at 6:25 AM 张小 <[email protected]> wrote:
>>>>>>
>>>>>>> C++ server send Capn Object to JavaClient like this
>>>>>>>
>>>>>>> capnp::MallocMessageBuilder message;
>>>>>>> Info::Builder info = message.initRoot<Info>();
>>>>>>> info.setId(123);
>>>>>>> kj::ArrayPtr<const kj::ArrayPtr<const capnp::word>> segments =
>>>>>>> message.getSegmentsForOutput();
>>>>>>>
>>>>>>> then I convert the  segments  object to char* send to java_client by
>>>>>>> proto rpc_call (bytes field)
>>>>>>>
>>>>>>>
>>>>>>> Then In java_client, I do like this to read the capn object
>>>>>>> com.google.protobuf.ByteString capn_object_bytes =
>>>>>>>  response.getCapnObject()
>>>>>>> SegmentReader segment = new
>>>>>>> SegmentReader(capn_object_bytes.asReadOnlyByteBuffer(), null);
>>>>>>> AnyPointer.Reader any = new AnyPointer.Reader(segment, 0,
>>>>>>> 64*1024*1024);
>>>>>>> Info.Reader info = any.getAs(Info.factory);
>>>>>>> System.out.println("Id:" + info.getId());
>>>>>>>
>>>>>>>
>>>>>>> run java_cliet ,happend error like this :
>>>>>>> Exception in thread "main" java.lang.NullPointerException
>>>>>>> at org.capnproto.WireHelpers.readStructPointer(WireHelpers.java:918)
>>>>>>> at
>>>>>>> org.capnproto.StructFactory.fromPointerReaderRefDefault(StructFactory.java:34)
>>>>>>> at
>>>>>>> org.capnproto.StructFactory.fromPointerReader(StructFactory.java:41)
>>>>>>> at
>>>>>>> org.capnproto.StructFactory.fromPointerReader(StructFactory.java:24)
>>>>>>> at org.capnproto.AnyPointer$Reader.getAs(AnyPointer.java:56)
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> 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].
>>>>>>> To view this discussion on the web visit
>>>>>>> https://groups.google.com/d/msgid/capnproto/081ab20b-5eae-43d5-a4fc-8230ef39d4a5%40googlegroups.com
>>>>>>> <https://groups.google.com/d/msgid/capnproto/081ab20b-5eae-43d5-a4fc-8230ef39d4a5%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>>
>>>>>> --
>>>>> 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].
>>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/capnproto/816c3227-c2b2-4b72-8ead-e707759a257c%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/capnproto/816c3227-c2b2-4b72-8ead-e707759a257c%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>> --
>>> 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].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/capnproto/1e177ff5-e49f-4d4a-b5f3-1c096604bb29%40googlegroups.com
>>> <https://groups.google.com/d/msgid/capnproto/1e177ff5-e49f-4d4a-b5f3-1c096604bb29%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> 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].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/capnproto/222eed4a-8f6a-48e7-828e-09235b228253%40googlegroups.com
> <https://groups.google.com/d/msgid/capnproto/222eed4a-8f6a-48e7-828e-09235b228253%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQkmz35p6qr2EC4TnT%3DADWN_mDoXkum3B%3D9SjbrTSD1y2Q%40mail.gmail.com.

Reply via email to