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

How to pass length of a string argument to CODE section in 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 获取长度?

首先,如果您在 XS 原型(和默认类型映射)中使用 char*,则您的代码存在错误。

你想要

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] 需要进行一些转换, 你需要指定哪一个。

在第一种情况下,字符串的每个字符都是 schar

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


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