如何将字符串参数的长度传递给XS中的CODE部分?

时间:2018-03-07 12:22:45

标签: perl xs

在XS中,我可以使用length keyword将字符串参数的长度传递给C函数:

static int foo(const char *s, size_t len)
{
    return 1;
}

MODULE = Foo        PACKAGE = Foo

void
foo(char *s, STRLEN length(s))

但是,如果我在CODE块中需要它,我怎样才能得到字符串的长度?

void
foo(char *s, STRLEN length(s))
CODE:
    ...
    foo(s, ???);

我可以使用STRLEN_length_of_sXSauto_length_of_s变量自动生成 通过 xsubpp 但感觉有点硬编码。有没有办法(可能是预定义的宏)我可以用来获取变量名称?或者我可以将自己的名称分配给长度参数吗?或者我是否需要将参数声明为SV *,然后在CODE部分中使用SvPV来获取长度?

1 个答案:

答案 0 :(得分:2)

首先,如果您在XS原型中使用char*(以及默认的typemap),那么您的代码就会出错。

你想要

void
foo(SV* sv)
PREINIT:
    STRLEN len;
    char* s;
CODE:
    s = SvPVbyte(sv, len);
    foo(s, len);

void
foo(SV* sv)
PREINIT:
    STRLEN len;
    char* s;
CODE:
    s = SvPVutf8(sv, len);
    foo(s, len);

请记住,Perl字符串是32位或64位数字的序列,而C字符串是8位字符的序列。 [1] 需要进行一些转换,并且需要指定哪一个。

在第一种情况下,字符串的每个字符都是char的{​​{1}}。

在第二种情况下,s将提供使用utf8编码的Perl字符串。

  1. 从技术上讲,s可能大于8位,但我不认为它可以在char支持的系统上。