[英]Perl API Inline C: How to get get a substr of a Perl byte string by reference without copying that string
你好社区我希望我能在这里遇到一些字节串专家。 我猜SvPVbyte会发挥作用,但是怎么样?
我的问题。 我已经成功解析了内联中的Perl数组XYZ(在数组的散列内),其中包含示例索引6789):
$testn=pnp($lengthofXYZ,\@{$XYZ{$_}});
内联C:
int pnp ( int n, SV *vertx)
AV *arrayx;
double val_of_interest;
arrayx = (AV *)SvRV( vertx );
SV **yi;
yi = av_fetch( arrayx, 6789, 0 );
val_of_interest = SvNV( *yi );
return calculation_with_val_of_interest
这非常有效。 但是让我说在Perl $ xyz =“\\ x09 \\ x07 \\ x44 \\ xaa ......中我有一个非常长的字节字符串(大约10-50MB)......
现在我想传递一个对这个SV的引用,并在C语言中通过这个字符串以9字节步长(substr like)行走,而不是在自己的C数组中完全复制它。
步行部分:前4个字节应根据参考4字节值ABC检查,该值也应在函数调用中。 如果有必要,我可以在之前解压缩“N”这个搜索短语并用整数调用函数。 如果postition 0没有成功跳转/增加9个字节,那么如果成功,我将把找到的位置作为返回。
非常感谢。
#include <stdint.h>
#include <string.h>
void foo(SV* sv) {
STRLEN len;
const char *buf = SvPVbyte(sv, len);
if (len < 4) {
/* ... Error ... */
}
uint32_t sig =
((unsigned char)(buf[0]) << 24) |
((unsigned char)(buf[1]) << 16) |
((unsigned char)(buf[2]) << 8) |
((unsigned char)(buf[3]) << 0);
buf += 4;
len -= 4;
if (sig != ...) {
/* ... Error ... */
}
while (len >= 9) {
char block[9];
memcpy(block, buf, 9);
buf += 9;
len -= 9;
/* ... Use block ... */
}
if (len > 0) {
/* ... Error ... */
}
}
[ 这是评论中问题的答案 ]
use bytes;
。 “强烈建议不要将此模块用于调试以外的任何其他目的。” (并且它实际上对调试没有用.Devel :: Peek更有用。) our
。 int
可能太小。 use strict;
use warnings qw( all );
use Inline C => <<'__EOS__';
SV* find_first_pos_of_43h_in_byte_string(SV* sv) {
STRLEN len;
const char *p_start = SvPVbyte(sv, len);
const char *p = p_start;
const char *p_end = p_start + len;
for (; p < p_end; ++p) {
if (*p == 0x43)
return newSVuv(p - p_start);
}
return newSViv(-1);
}
__EOS__
my $buf = "\x00\x00\x43\x01\x01\x01";
my $pos = find_first_pos_of_43h_in_byte_string($buf);
当然,你可以简单地使用
use strict;
use warnings qw( all );
my $buf = "\x00\x00\x43\x01\x01\x01";
my $pos = index($buf, chr(67));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.