该uint64_t
类型未在默认中定义typemap
,它随 Perl 发行版一起提供。根据perlxstypemap
:
xsubpp
在更实际的术语中,类型映射是编译器用来将 C 函数参数和值映射到 Perl 值的代码片段的集合。
您可以定义自己的typemap
(在与文件相同的目录中.xs
)。它可能看起来像:
TYPEMAP
unsigned long long T_U_LONG_LONG
uint64_t T_U_LONG_LONG # equivalent to typedef unsigned long long uint64_t;
INPUT
T_U_LONG_LONG
$var = (unsigned long long)SvUV($arg)
OUTPUT
T_U_LONG_LONG
sv_setuv($arg, (UV)$var);
我不确定这些映射,尤其是SvUV
部分映射,UV
因此您需要在任何真实代码中仔细测试它。我怀疑它们只是“普通”整数,因此uint64_t
仅在内部使用时才具有完整功能,即在函数定义范围内。
请注意,根据 C 标准(自 C99 起),unsigned long long
类型至少为64 位宽,但在我知道的每个实现中它都是 64 位的。
与test.xs
:
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
MODULE = test PACKAGE = test
unsigned int
u64_mul_high(a, b)
unsigned int a
unsigned int b
CODE:
RETVAL = ((uint64_t) a * b) >> 32;
OUTPUT:
RETVAL
并test.pl
定义为:
#!/usr/bin/perl
use ExtUtils::testlib;
use test;
print test::u64_mul_high(2147483647, 1000), "\n";
您会得到以下结果:
499 (0001 1111 0011)
这是32-bit x 32-bit
乘法的较高 32 位肢体,结果为 64 位整数。
我在 32 位 GNU/Linuxsizeof(long) = 4
和 Perl 5.10 上检查了这一点。