I am trying to facilitate the movement of binary data between Perl and my C ++ library.
I created a C ++ structure to pass binary_data data:
struct binary_data { unsigned long length; unsigned char *data; };
In my SWIG interface file for me there is the following:
%typemap(in) binary_data * (binary_data temp) { STRLEN len; unsigned char *outPtr; if(!SvPOK($input)) croak("argument must be a scalar string"); outPtr = (unsigned char*) SvPV($input, len); printf("set binary_data '%s' [%d] (0x%X)\n", outPtr, len, $input); temp.data = outPtr; temp.length = len; $1 = &temp; } %typemap(out) binary_data * { SV *obj = sv_newmortal(); if ($1 != 0 && $1->data != 0 && $1->length > 0) { sv_setpvn(obj, (const char*) $1->data, $1->length); printf("get binary_data '%s' [%d] (0x%X)\n", $1->data, $1->length, obj); } else { sv_setsv(obj, &PL_sv_undef); printf("get binary_data [set to undef]\n"); } if( !SvPOK(obj) ) croak("The result is not a scalar string"); $result = obj; }
I create my Perl module through "ExtUtils :: MakeMaker", and all this is good.
Then I run the following perl script test to ensure that the set / get binary data from the perl string is correct.
my $fr = ObjectThatContainsBinaryData->new(); my $data = "1234567890"; print ">>>PERL:swig_data_set\n"; $fr->swig_data_set($data); print "<<<PERL:swig_data_set\n"; print ">>>PERL:swig_data_get\n"; my $rdata = $fr->swig_data_get(); print "<<<PERL: swig_data_get\n"; print "sent :" . \$data . " len=" . length($data). " '$data'\n" ."recieved:". \$rdata. " len=" . length($rdata). " '$rdata'\n";
Now combined C ++ and Perl printf stdout:
>>>PERL:swig_data_set set binary_data '1234567890' [10] (0x12B204D0) <<<PERL:swig_data_set >>>PERL:swig_data_get get binary_data '1234567890' [10] (0x1298E4E0) <<<PERL: swig_data_get sent :SCALAR(0x12b204d0) len=10 '1234567890' recieved:SCALAR(0x12bc71c0) len=0 ''
So why does it look like the perl sv_setpvn call is not working or not working? I donβt know why, when I print the returned binary data in perl, it appears as an empty scalar, but it looks great in the built-in standard SWIG C ++ map.
I use:
Perl v5.8.8 for x86_64-linux-thread-multi
SWIG 2.0.1
gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)