如何从没有副本的空终止字符串创建SV值?喜欢newSVpv(const char*, STRLEN)
但没有副本和移动所有权到Perl(因此Perl必须释放该字符串内存).我需要这个来避免大量的内存分配和复制.
我找到了以下示例:
SV *r = sv_newmortal();
SvPOK_on(r);
sv_usepvn_mg(r, string, strlen(string) + 1);
Run Code Online (Sandbox Code Playgroud)
但我对XS内部结构并不十分了解并且有一些疑问.
如果您希望Perl管理内存块,它需要知道如何重新分配它并释放它.它知道如何重新分配和释放的唯一内存是使用其分配器分配的内存Newx
.(否则,它必须将reallocator和deallocator与每个内存块相关联.)
如果无法使用分配内存块Newx
,那么最佳选择可能是创建一个SvLEN
设置为零的只读SV .这告诉Perl它不拥有内存.SV可以被祝福成一个具有析构函数的类,该析构函数将使用适当的deallocator释放内存.
如果您可以使用分配内存块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;
}
Run Code Online (Sandbox Code Playgroud)
注意:ptr
应该指向由其分配的内存Newx
,并且它必须指向返回的块的开头Newx
.
注意:接受标志SVf_UTF8
(指定ptr
是在Perl中看到的字符串的UTF-8编码),SVs_TEMP
(sv_2mortal
调用SV)和SV_HAS_TRAILING_NUL
(见下文).
注意:某些代码期望标量的字符串缓冲区具有尾随NUL(即使缓冲区的长度已知,即使缓冲区可以包含NUL).如果您分配的内存块具有超出数据末尾的尾随NUL(例如,C样式的NUL终止字符串),则传递该SV_HAS_TRAILING_NUL
标志.如果没有,该函数将尝试扩展缓冲区并添加NUL.
归档时间: |
|
查看次数: |
397 次 |
最近记录: |