On Fri, Sep 05, 2008 at 09:46:57PM +0200, Jeffrey Ratcliffe wrote:

> http://www.sane-project.org/html/doc011.html#s4.2.6: Access to a
> scanner is provided through an opaque type called SANE_Handle. The C
> declaration of this type is given below.
> 
>     typedef void *SANE_Handle;
> 
> While this type is declared to be a void pointer, an application must
> not attempt to interpret the value of a SANE_Handle. In particular,
> SANE does not require that a value of this type is a legal pointer
> value.
> 
> So in the typemap I have:
> 
> SANE_Handle                   T_OPAQUEPTR
> 
> I assume that newSVpv(h, 0) is causing me the trouble. I can't work
> out what is correct.

newSVpv() is documented as:

  Creates a new SV and copies a string into it.  The reference count for the
  SV is set to 1.  If C<len> is zero, Perl will compute the length using
  strlen().  For efficiency, consider using C<newSVpvn> instead.
    
        SV*     newSVpv(const char *const s, const STRLEN len)

So yes, it's doing a strlen() because you specify the length as 0. To do what
you wanted to do, you wanted newSVpvn():

  Creates a new SV and copies a string into it.  The reference count for the
  SV is set to 1.  Note that if C<len> is zero, Perl will create a zero length
  string.  You are responsible for ensuring that the source string is at least
  C<len> bytes long.  If the C<s> argument is NULL the new SV will be undefined.
  
        SV*     newSVpvn(const char *const s, const STRLEN len)



But I'm not even sure that that's sensible. Your typemap is

> void
> sane_open(class, name)
>               SANE_String_Const       name
>       INIT:
>               SANE_Status             status;
>                 SANE_Handle           h;
>         PPCODE:
>               status = sane_open(name, &h);
>                 XPUSHs(sv_2mortal(newSViv(status)));
> 126->                XPUSHs(sv_2mortal(newSVpv(h, 0)));


So what you're doing is a moderately expensive way of creating an empty string.
You're not storing the value of h itself.

Assuming that you wanted to store the value of h, I don't know what the best
thing to do is, and I have to stop typing now as food is served.

Nicholas Clark

Reply via email to