On Mon, 10 Apr 2006, Sergey Skvortsov wrote:
Igor Sysoev wrote:
On Thu, 6 Apr 2006, Igor Sysoev wrote:
is the effective way to return data from XS to perl without unnecessary
memory coping ? As I understand
1) if I return char*, then perl creates SV and copies the string to SV.
If you allocate *out with your own allocator (and *out must not be freed
with Safefree() on SV destruction) you can use another approach:
char *my_c_func(const char *in, STLEN len_in, STLEN *len_out) {
char *out;
*len_out = len_in; // or other pre-calculated value
out = my_alloc(*len_out); // sic!
// process *in => *out
return out;
}
MODULE = XXX
PROTOTYPES: DISABLE
void
myfunc(in)
CODE:
{
STRLEN len_in, len_out;
char *out;
char *in = SvPV(ST(0), len_in);
SV *res;
out = my_c_func(in, len, &len_out);
res = sv_newmortal();
sv_upgrade(sv, SVt_PV);
SvPOK_on(res);
SvPV_set(res, out);
SvLEN_set(res, len_out+1);
SvCUR_set(res, len_out);
SvFAKE_on(res); // trick!!!
SvREADONLY_on(res); // FAKE/READONLY will be reset
// on string change/normalization
// and PVX will be copied to new
// allocated string
ST(0) = res;
XSRETURN(1);
}
Thank you, Sergey. This is exactly what I need: I use own allocator
and my data should not be free()d by perl.
Fairly, there is even more speedup hacks. For example, you can use
TARG-macros, if you allocate string with Newx() call.
Could you explain in detail ?
By the way, is it possible to avoid creating my mortal SV and create just
perl SV ?
Igor Sysoev
http://sysoev.ru/en/