The uint64_t
type is not defined in default typemap
, that comes with Perl distribution. According to 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.
You can define your own typemap
(in the same directory as .xs
file). It might look like:
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);
I am not sure about these mappings, especially SvUV
and UV
part, so you need to test it carefully in any real code. I suspect that they are just "plain" integers, thus uint64_t
is fully functional only for internal usage, that is within function's definition.
Note that unsigned long long
type is at least 64-bits wide according to C Standard (since C99), but it's 64-bit on every implementation I am aware of.
With test.xs
as:
#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
and test.pl
defined as:
#!/usr/bin/perl
use ExtUtils::testlib;
use test;
print test::u64_mul_high(2147483647, 1000), "\n";
you get an result of:
499 (0001 1111 0011)
that is higher 32-bit limb of an 32-bit x 32-bit
multiplication that results into 64-bit integer.
I checked this on 32-bit GNU/Linux with sizeof(long) = 4
and Perl 5.10.
U32
etc sounds like unsigned, while the term integer normally includes the negative range) – IngroupMath::Int64
as advised bellow. – Epode