From: Rene R. <re...@ex...> - 2006-09-04 07:24:42
|
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: =2D-- 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) { =2D 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; =2D 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 |