NativeCall and Inline Languages

47.1 NativeCall (Call C Libraries)

Native types: int8..int64, uint8..uint64, num32, num64, size_t, long, bool, Str (with is encoded('utf8')), Pointer[T], CArray[T], Buf/Blob, and representations (CStruct, CPointer, CUnion).

Tools: App::GPTrixie (generate bindings from headers), NativeHelpers::Blob.

use NativeCall;

# libc functions (is native with no library = the current process / libc)
sub strlen(Str --> size_t) is native {*}
sub getpid(--> int32) is native {*}
say strlen('Raku'), ' ', getpid();

# A specific library
sub sqlite3_libversion(--> Str) is native('sqlite3') {*}
say sqlite3_libversion();

# Rename with is symbol
sub c-puts(Str --> int32) is native is symbol('puts') {*}
c-puts('Hello from C');

# Structs
class Point is repr('CStruct') {
    has num64 $.x;
    has num64 $.y;
}

# Pointers, arrays and callbacks
sub qsort(CArray[int32], size_t, size_t, &compare (Pointer[int32], Pointer[int32] --> int32)) is native {*}
my @nums := CArray[int32].new(5, 3, 9, 1);
qsort(@nums, 4, nativesizeof(int32), sub ($a, $b --> int32) { ($a.deref <=> $b.deref).Int });   # Order → -1/0/1
say @nums.list;                           # (1 3 5 9)

# Your own C library
# mylib.c: int add(int a, int b) { return a + b; }  →  gcc -shared -fPIC -o libmylib.so mylib.c
sub add(int32, int32 --> int32) is native('./mylib') {*}

47.2 Inline::Perl5 and Inline::Python

:from<Perl5> makes the entire CPAN available to Raku code, and Raku objects can be passed to Perl and back.

use Inline::Perl5;                         # zef install Inline::Perl5 (needs a Perl with libperl)
use Text::CSV_XS:from<Perl5>;              # use any CPAN module directly!
use Digest::MD5:from<Perl5> <md5_hex>;
say md5_hex('raku');

my $p5 = Inline::Perl5.new;
say $p5.run('join ",", map { $_ * 2 } 1..5');   # 2,4,6,8,10

use Inline::Python;                        # zef install Inline::Python
my $py = Inline::Python.new;
say $py.run('2 ** 10', :eval);             # 1024
$py.run('import math');
say $py.call('math', 'sqrt', 16);