加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

使用SWIG将二进制数据移入/移出Perl

发布时间:2020-12-16 06:16:34 所属栏目:大数据 来源:网络整理
导读:我试图让我很容易在Perl和我的C库之间移动二进制数据. 我创建了一个c结构来处理binary_data: struct binary_data { unsigned long length; unsigned char *data;}; 在我的SWIG界面文件中,我有以下内容: %typemap(in) binary_data * (binary_data temp) { S
我试图让我很容易在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_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调用失败或无效?
我不知道为什么当我在perl中打印返回的二进制数据时,它显示为空标量,但在SWIG C嵌入式类型映射中看起来很好.

我正在使用:

为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文档:


30.8.2返回值

返回值放在每个包装函数的参数堆栈上.参数堆栈指针的当前值包含在变量argvi中.每当添加新的输出值时,增加该值是至关重要的.对于多个输出值,argvi的最终值应为输出值的总数.“

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读