5

perlapiによると、次のようにsv_catpv()動作します。

NULで終わる文字列を、SV にある文字列の末尾に連結します。SV に UTF-8 ステータスが設定されている場合、追加されるバイトは有効な UTF-8 である必要があります。「get」マジックは処理しますが、「set」マジックは処理しません。

void sv_catpv(SV *const sv, const char* ptr)

私が見つけたほとんどの XS チュートリアルでは、次のように使用さsv_catpvs()れています。

と同様sv_catpvnですが、文字列/長さのペアの代わりにリテラル文字列を取ります。

void sv_catpvs(SV* sv, const char* s)

それはあまり役に立たないので、sv_catpvn()次を見てみましょう。

SV にある文字列の末尾に文字列を連結します。はlen、コピーするバイト数を示します。SV に UTF-8 ステータスが設定されている場合、追加されるバイトは有効な UTF-8 である必要があります。「get」マジックは処理しますが、「set」マジックは処理しません。

void sv_catpvn(SV *dsv, const char *sstr, STRLEN len)

したがって、sv_catpvnsv_catpv、文字列の長さを別のパラメーターとして受け取ることを除いてsv_catpvsと同じsv_catpvnことを行い、リテラル文字列を受け取ることを除いて と同じです。

sv_catpvと の間に微妙な違いがありますかsv_catpvs、それとも同じことを行うための2つの方法にすぎませんか?

4

1 に答える 1

6

あなたが引用した一節によると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, "foo", 3, SV_GMAGIC)

コンパイル時。sv_catpv一方、より遅い を使用することを余儀なくされていますstrlen

于 2014-10-29T18:37:33.203 に答える