c – 使用Perl XS的64位整数

前端之家收集整理的这篇文章主要介绍了c – 使用Perl XS的64位整数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想使用64位整数将一个C函数移植到Perl代码.为此,我使用Perl XS.

我的问题是Perl XS类型中没有64位整数(只有U32,U16和U8).

那么,在Perl XS代码中使用64位整数的最佳方法是什么?

这是我想要做的代码示例:

uint64_t
foo(integer)
   uint64_t integer

   CODE:
      RETVAL = foo(integer);

   OUTPUT:
      RETVAL

foo()有C原型:

uint64_t foo(uint64_t);

我没有在perlxs文档和stackoverflow.com中找到任何有用的东西.

解决方法

uint64_t类型未在默认类型映射中定义,它与Perl分发一起提供.根据 perlxstypemap

In more practical terms,the typemap is a collection of code fragments
which are used by the xsubpp compiler to map C function parameters and
values to Perl values.

您可以定义自己的类型映射(与.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开始),无符号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位x 32位乘法的32位高,导致64位整数.

我在32位GNU / Linux上检查了这个,其中sizeof(long)= 4和Perl 5.10.

猜你在找的C&C++相关文章