我希望能够轻松地在Perl和我的C++库之间移动二进制数据。
我创建了一个C++结构来处理binary_data:
struct binary_data {
unsigned long length;
unsigned char *data;
};
在我的SWIG接口文件中,我有以下内容:
%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;
}
我使用"ExtUtils::MakeMaker"来构建我的Perl模块,效果不错。
然后我运行下面的Perl测试脚本以确保二进制数据能够正确地从Perl字符串中设置/获取。
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";
现在结合使用C++和Perl的printf标准输出是:
>>>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 ''
那么为什么perl调用< strong>sv_setpvn< /strong>似乎失败或无法工作呢?我不知道为什么当我在perl中打印返回的二进制数据时,它显示为空标量,但是在SWIG C++嵌入式类型映射中看起来很好。 我正在使用:Perl v5.8.8 built for x86_64-linux-thread-multi、SWIG 2.0.1和gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)。