Perl SV 值来自指针,无需复制

  • 本文关键字:复制 指针 SV Perl perl xs
  • 更新时间 :
  • 英文 :


如何在不复制的情况下从以空结尾的字符串创建 SV 值?像newSVpv(const char*, STRLEN)但没有副本,并将所有权转移到Perl(所以Perl必须释放字符串内存)。我需要这个来避免巨大的内存分配和复制。

我找到了以下示例:

SV *r = sv_newmortal();
SvPOK_on(r);
sv_usepvn_mg(r, string, strlen(string) + 1);

但我对XS内部没有深入的了解,并且有一些疑问。

如果你想让

Perl 管理内存块,它需要知道如何重新分配和解分配它。它知道如何重新分配和释放的唯一内存是使用其分配器分配的内存Newx 。(否则,它必须将重新分配器和解除分配器与每个内存块相关联。

如果无法使用 Newx 分配内存块,则最佳选择可能是创建SvLEN设置为零的只读 SV。这告诉 Perl 它不拥有内存。该 SV 可以祝福到一个具有析构函数的类中,该析构函数将使用适当的释放器释放内存。

如果可以使用 Newx 分配内存块,则可以使用以下方法:

SV* newSVpvn_steal_flags(pTHX_ const char* ptr, STRLEN len, const U32 flags) {
#define newSVpvn_steal_flags(a,b,c) newSVpvn_steal_flags(aTHX_ a,b,c)
    SV* sv;
    assert(!(flags & ~(SVf_UTF8|SVs_TEMP|SV_HAS_TRAILING_NUL)));
    sv = newSV(0);
    sv_usepvn_flags(sv, ptr, len, flags & SV_HAS_TRAILING_NUL);
    if ((flags & SVf_UTF8) && SvOK(sv)) {
        SvUTF8_on(sv);
    }
    SvTAINT(sv);
    if (flags & SVs_TEMP) {
        sv_2mortal(sv);
    }
    return sv;
}

注意:ptr 应指向 Newx 分配的内存,并且必须指向 Newx 返回的块的开头。

注意:接受标志SVf_UTF8(指定ptr是要在 Perl 中看到的字符串的 UTF-8 编码)、SVs_TEMP(在 SV 上调用sv_2mortal)和SV_HAS_TRAILING_NUL(见下文)。

注意:某些代码期望标量的字符串缓冲区具有尾随 NULL(即使缓冲区的长度是已知的,即使缓冲区可以包含 NULL)。如果您分配的内存块在数据末尾之外具有尾随 NULL(例如,C 样式的 NUL 终止字符串),则传递 SV_HAS_TRAILING_NUL 标志。如果没有,该函数将尝试扩展缓冲区并添加 NUL。

相关内容

  • 没有找到相关文章

最新更新