3

次のようなコードがあるとしましょう。

  my $str = 'some text';
  my $result = my_subroutine($str);

そして、my_subroutine()PerlXSコードとして実装する必要があります。たとえば、(Unicode)文字列のバイトの合計を返すことができます。

XSコードで、文字列を処理する方法 a)一般的な方法としてcharごと、および(b)文字列がASCIIコードサブセット(ネイティブから変換する組み込み関数)で構成されている場合はバイトごとchar []への文字列のデータ構造?

4

2 に答える 2

3

バイトを期待している場合:

STRLEN len;
char* buf = SvPVbyte(sv, len);

while (len--) {
   char byte = *(buf++);

   ... do something with byte ...
}

テキストまたはバイト以外の文字を期待している場合:

STRLEN len;
U8* buf = SvPVutf8(sv, len);

while (len) {
   STRLEN ch_len;
   UV ch = utf8n_to_uvchr(buf, len, &ch_len, 0);
   buf += ch_len;
   len -= ch_len;

   ... do something with ch ...
}
于 2012-05-16T17:23:49.717 に答える
3

XSレイヤーでは、バイトまたはUTF-8文字列を取得します。一般的なケースでは、コードにchar *文字列内の次の項目を指すtoが含まれている可能性があり、それが進むにつれて増分されます。XSで使用するUTF-8サポート関数の便利なセットについては、の「Unicodeサポート」セクションをお読みください。perlapi


http://cpansearch.perl.org/src/PEVANS/Tickit-0.15/lib/Tickit/Utils.xsからの私の例

int textwidth(str)
    SV *str
  INIT:
    STRLEN len;
    const char *s, *e;

  CODE:
    RETVAL = 0;

    if(!SvUTF8(str)) {
      str = sv_mortalcopy(str);
      sv_utf8_upgrade(str);
    }

    s = SvPV_const(str, len);
    e = s + len;

    while(s < e) {
      UV ord = utf8n_to_uvchr(s, e-s, &len, (UTF8_DISALLOW_SURROGATE
                                               |UTF8_WARN_SURROGATE
                                               |UTF8_DISALLOW_FE_FF
                                               |UTF8_WARN_FE_FF
                                               |UTF8_WARN_NONCHAR));
      int width = wcwidth(ord);
      if(width == -1)
        XSRETURN_UNDEF;

      s += len;
      RETVAL += width;
    }

  OUTPUT:
    RETVAL

簡単に言うと、この関数は、指定された文字列を一度に1つのUnicode文字で繰り返し、。で指定された幅を累積しwcwidth()ます。

于 2012-05-16T16:31:41.110 に答える