gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 01:30:14 27 4
gpt4 key购买 nike

我试图让我可以轻松地在 Perl 和我的 C++ 库之间移动二进制数据。

我创建了一个 c++ 结构来处理 binary_data:

struct binary_data {
unsigned long length;
unsigned char *data;
};

在我的 SWIG 接口(interface)文件中,我有以下内容:
%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 ''

那么为什么看起来对 sv_setpvn 的 perl 调用失败或不起作用?
我不知道为什么当我在 perl 中打印返回的二进制数据时,它显示为一个空标量,但它在 SWIG C++ 嵌入式类型映射中看起来很好。

我正在使用:

为 x86_64-linux-thread-multi 构建的 Perl v5.8.8

痛饮 2.0.1

gcc 版本 4.1.1 20070105(红帽 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 字符串。
SV = PV(0x1eae7d40) at 0x1eac64d0
REFCNT = 1
FLAGS = (PADBUSY,PADMY,POK,pPOK)
PV = 0x1eb25870 "1234567890"\0
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的最终值应该是输出值的总数。
"

关于perl - 使用 SWIG 将二进制数据移入/移出 Perl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5251451/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com