How I could create SV value from null terminated string without copy? Like newSVpv(const char*, STRLEN)
but without copy and with moving ownership to Perl (so Perl must release that string memory). I need this to avoid huge memory allocation and copy.
I found following example:
SV *r = sv_newmortal();
SvPOK_on(r);
sv_usepvn_mg(r, string, strlen(string) + 1);
But I don't have deep knowledge of XS internals and have some doubts.
If you want Perl to manage the memory block, it needs to know how to reallocate it and deallocate it. The only memory it knows how to reallocate and deallocate is memory allocated using its allocator,
Newx
. (Otherwise, it would have to associate a reallocator and deallocator with each memory block.)If you can't allocate the memory block using
Newx
, then your best option might be to create a read-only SV withSvLEN
set to zero. That tells Perl that it doesn't own the memory. That SV could be blessed into a class that has a destructor that will deallocate the memory using the appropriate deallocator.If you can allocate the memory block using
Newx
, then you can use the following:Note:
ptr
should point to memory that was allocated byNewx
, and it must point to the start of the block returned byNewx
.Note: Accepts flags
SVf_UTF8
(to specify thatptr
is the UTF-8 encoding of the string to be seen in Perl),SVs_TEMP
(to havesv_2mortal
called on the SV) andSV_HAS_TRAILING_NUL
(see below).Note: Some code expects the string buffer of scalars to have a trailing NUL (even though the length of the buffer is known and even though the buffer can contain NULs). If the memory block you allocated has a trailing NUL beyond the end of the data (e.g. a C-style NUL-terminated string), then pass the
SV_HAS_TRAILING_NUL
flag. If not, the function will attempt to extend the buffer and add a NUL.