On Thu, Aug 23, 2012 at 5:06 PM, Darryl L. Pierce <dpie...@redhat.com>wrote:

> On Thu, Aug 23, 2012 at 04:02:09PM -0400, Rafael Schloming wrote:
> > I'm a little confused by what you're trying to do with the wrapper. This
> is
> > what I have for the wrapper in my ruby.i:
> >
> > int pn_message_save(pn_message_t *msg, char *OUTPUT, size_t
> *OUTPUT_SIZE);
> > %ignore pn_message_save;
>
> With the above the error happens at 65 characters. I took out my wrapper
> and ran the test again and it crashes at 65 characters every time.
>

Can you post the test snippet so I can try?


>
> > I believe this is all that is necessary since the standard typemaps
> should
> > pick up on OUTPUT and OUTPUT_SIZE and just do the right thing.
>
> What I would like to see in the dynamic languages for this is to not
> even have to specify the size for the output buffer; i.e., just call:
>
> Qpid::Proton.get_message_data(msg)
>
> and get the data back as one lump.
>

Ah, in that case I think you want to use ALLOC_OUTPUT and ALLOC_SIZE. Your
wrapper will need to be a little bit smarter though. There is no way to
know in advance how much space it will take to encode the message in a
given format, so the wrapper will have to pick an initial size and then
keep on doubling until it fits.

Here is an example of the ALLOC stuff. Obviously the wrapper would need to
be different.

%rename(pn_delivery_tag) wrap_pn_delivery_tag;
%inline %{
  void wrap_pn_delivery_tag(pn_delivery_t *delivery, char **ALLOC_OUTPUT,
size_t *ALLOC_SIZE) {
    pn_delivery_tag_t tag = pn_delivery_tag(delivery);
    *ALLOC_OUTPUT = malloc(tag.size);
    *ALLOC_SIZE = tag.size;
    memcpy(*ALLOC_OUTPUT, tag.bytes, tag.size);
  }
%}
%ignore pn_delivery_tag;

The swig chapter on C string handle is a good reference for this stuff.
There might be some other macros there that are useful:

  http://www.swig.org/Doc2.0/SWIGDocumentation.html#Library_nn8


> > Regardless, I think the cause for the issue is that your wrapper function
> > is assuming pn_message_save returns a signed size, but actually it
> returns
> > an int that is 0 on success or an error code on failure:
> >
> >   int pn_message_save(pn_message_t *message, char *data, size_t *size);
> >
> > On success the size of the output data is stored into *size. (I'll add
> some
> > API-doc for this.)
> >
> > As an aside in looking at this I noticed that there is some duplication
> > between the php, ruby, and python files that could be consolidated into
> the
> > cproton.i. I think this particular declaration is part of that
> duplication
> > unless there is some reason I'm missing that it has to be different for
> > ruby.
>
> Agreed. Also, we should make sure to remove having the individual
> languages include them relatively (i.e., %include "../cproton.i") and
> instead place the shared files in the include directory.
>

+1

--Rafael

Reply via email to