Concatenates the
NUL
-terminated string onto the end of the string which is in the SV. If the SV has the UTF-8 status set,then the bytes appended should be valid UTF-8. Handles ‘get’ magic,but not ‘set’ magic.@H_404_20@
void sv_catpv(SV *const sv,const char* ptr)
我发现的大多数XS教程都使用sv_catpvs(),这样做:
Like
sv_catpvn
,but takes a literal string instead of a string/length pair.@H_404_20@
void sv_catpvs(SV* sv,const char* s)
嗯,这不是很有帮助,所以让我们看一下sv_catpvn():
Concatenates the string onto the end of the string which is in the SV. The
len
indicates number of bytes to copy. If the SV has the UTF-8 status set,but not ‘set’ magic.@H_404_20@
void sv_catpvn(SV *dsv,const char *sstr,STRLEN len)
因此,sv_catpvn与sv_catpv做同样的事情,除了它将字符串长度作为单独的参数,并且sv_catpvs与sv_catpvn相同,除了它采用文字字符串.
sv_catpv和sv_catpvs之间是否存在一些我缺失的细微差别,或者它们只是两种方式来做同样的事情?
解决方法
const char *str = "foo"; sv_catpvs(sv,"foo"); // ok sv_catpvs(sv,str); // ERROR
另一方面,sv_catpv接受任何返回字符串的表达式.
sv_catpv(sv,"foo"); // ok sv_catpv(sv,str); // ok
那么为什么sv_catpvs存在呢?因为它更快. sv_catpvs只需要一个字符串文字的原因是它是一个扩展的宏
sv_catpvs(sv,"foo")
变成类似的东西
sv_catpvn_flags(sv,"foo",sizeof("foo")-1,SV_GMAGIC)
哪个解决了
sv_catpvn_flags(sv,3,SV_GMAGIC)
在编译时.另一方面,sv_catpv被迫使用较慢的strlen.