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