From: Rene R. <re...@ex...> - 2006-09-04 09:58:39
|
Hi, One of this patches would be nice to have upstream in a upcomming SWIG release. The one I prefer: =2D-- Lib/perl5/perlstrings.swg 2006-09-04 11:53:14.000000000 +0200 +++ new2 2006-09-04 11:52:43.000000000 +0200 @@ -44,15 +44,7 @@ { SV *obj =3D sv_newmortal(); if (size && carray) { =2D if (carray[size - 1] =3D=3D 0) { =2D sv_setpv(obj, carray); =2D } else { =2D char *tmp =3D %new_array(size + 1, char); =2D memcpy(tmp, carray, size); =2D tmp[size] =3D 0; =2D sv_setpv(obj, tmp); =2D %delete_array(tmp); =2D } + sv_setpvn(obj, carray, size); } else { sv_setsv(obj, &PL_sv_undef); } An alternative that would also be "acceptable", though it would mess binary data by adding a superflous and potentially irritating terminating zero ... =2D-- Lib/perl5/perlstrings.swg 2006-09-04 11:53:14.000000000 +0200 +++ new1 2006-09-04 11:53:48.000000000 +0200 @@ -45,12 +45,12 @@ SV *obj =3D sv_newmortal(); if (size && carray) { if (carray[size - 1] =3D=3D 0) { =2D sv_setpv(obj, carray); + sv_setpvn(obj, carray, size); } else { char *tmp =3D %new_array(size + 1, char); memcpy(tmp, carray, size); tmp[size] =3D 0; =2D sv_setpv(obj, tmp); + sv_setpvn(obj, tmp, size+1); %delete_array(tmp); } } else { See also: On Monday 04 September 2006 09:24, Rene Rebe wrote: > Hello again, > > On Sunday 03 September 2006 22:03, Rene Rebe wrote: > > Hi all, > > > > while using SWIG to bridge a C++ (imaging) library with e.g. Perl I run > > into a problem with &cstring_output_allocate_size. > > > > Among the functions I export is one to store the encoded image in > > the system memory. > > > > According the SWIG documentation %cstring_output_allocate_size > > should be what I need "This macro is used to return strings that are > > allocated within the program and ... the returned string may contain > > binary data.". > > > > However in my case the Perl scalar I get is terminated at the first > > embedded binary 0. > > > > I use Perl-5.8.8 and SWIG-1.3.29. > > > > Fragments of my code so far (simplified for the list): > > > > #ifdef SWIG > > %cstring_output_allocate_size( char ** s, int *slen, free(*$1)) > > #endif > > void encodeImage (char **s, int *slen, > > Image* image, const char* codec, int quality, > > const char* compression); > > > > ... > > > > void encodeImage (char **s, int *slen, > > Image* image, const char* codec, int quality, > > const char* compression) > > { > > // just for testing ... > > std::ostringstream stream (""); // empty string to start with > > > > stream << '1'; << '2' << '\0' << '3' << '4'; > > stream.flush(); > > > > std::cerr << "c++> size: " << stream.str().size() << std::endl; > > > > char* payload =3D (char*) malloc (stream.str().size()); > > memcpy (payload, stream.str().c_str(), stream.str().size()); > > > > *s =3D payload; > > *slen =3D stream.str().size(); > > } > > > > and when I call it from Perl: > > > > $image_bits =3D ExactImage::encodeImage ($image, "jpeg", 80, ""); > > print "perl> size: " . length($image_bits) . "\n"; > > > > I get: > > > > c++> size: 5 > > perl> size: 2 > > > > When I look at the code generated from SWIG I noticed: > > > > if (argvi >=3D items) EXTEND(sp,1); ST(argvi) =3D > > SWIG_FromCharPtrAndSize(*arg1,*arg2); argvi++ ; > > > > and wonder if that function is the right thing to call there as > > it only sets the pointer and no size in the target object. > > > > Can someone confirm I hit a SWIG bug to be fixed or is there > > some other function that I should use instead? > > > > Thanks in advance, > > Now, when I go on and tweak the SWIG generated file to use sv_setpvn > instead of just svn_setpv: > > --- api-perl-wrap.cc 2006-09-04 09:21:11.000000000 +0200 > +++ api-perl-wrap.cc.fixed 2006-09-04 09:21:05.000000000 +0200 > @@ -1630,12 +1630,12 @@ > SV *obj =3D sv_newmortal(); > if (size && carray) { > if (carray[size - 1] =3D=3D 0) { > - sv_setpv(obj, carray); > + sv_setpvn(obj, carray, size); > } else { > char *tmp =3D (new char[size + 1]); > memcpy(tmp, carray, size); > tmp[size] =3D 0; > - sv_setpv(obj, tmp); > + sv_setpvn(obj, carray, size); > delete[] tmp; > } > } else { > > I get my data back into Perl as intended. > > Again, do I misuse the SWIG typemaps or is this a SWIG bug that > should be addressed properly? > > Yours, =2D-=20 Ren=E9 Rebe - ExactCODE - Berlin (Europe / Germany) http://exactcode.de | http://t2-project.org | http://rene.rebe.name +49 (0)30 / 255 897 45 |