使用SWIG将二进制数据移入/移出Perl
我试图让我很容易在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测试脚本以确保二进制数据正在运行 my $fr = ObjectThatContainsBinaryData->new(); my $data = "1234567890"; print ">>>PERL:swig_data_setn"; $fr->swig_data_set($data); print "<<<PERL:swig_data_setn"; print ">>>PERL:swig_data_getn"; my $rdata = $fr->swig_data_get(); print "<<<PERL: swig_data_getn"; 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 '' 那么为什么看起来对sv_setpvn的perl调用失败或无效? 我正在使用: 为x86_64-linux-thread-multi构建的Perl v5.8.8 SWIG 2.0.1 gcc版本4.1.1 20070105(Red Hat 4.1.1-52) 解决方法
如果替换%typemap(out)中的以下行:
$result = obj; 同 $result = obj; argvi++; //This is a hack to get the hidden stack pointer to increment before the return SWIG生成的代码现在看起来像: ... ST(argvi) = obj; argvi++; } XSRETURN(argvi); } 并且您的测试脚本将按预期返回Perl String. SV = PV(0x1eae7d40) at 0x1eac64d0 REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK) PV = 0x1eb25870 "1234567890" CUR = 10 LEN = 16 <<<PERL: swig_data_get sent :SCALAR(0x1ea64530) len=10 '1234567890' recieved:SCALAR(0x1eac64d0) len=10 '1234567890' 您应该更仔细地阅读有关Perl中的类型映射的SWIG 2.0文档: “ 返回值放在每个包装函数的参数堆栈上.参数堆栈指针的当前值包含在变量argvi中.每当添加新的输出值时,增加该值是至关重要的.对于多个输出值,argvi的最终值应为输出值的总数.“ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |