Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly use CPointer and CStruct in NativeCall interface

I am trying to get this example of NativeCall running:

use NativeCall;

class p_timespec is repr('CPointer') {
    has uint32 $.tv_sec;
    has long $.tv_nanosecs;
}

sub clock_gettime(uint32 $clock-id, p_timespec $tspec --> uint32) is native(Str) { * };

my p_timespec $this-time;

my $result = clock_gettime( 0, $this-time);

say "$result, $this-time";

It simply segfaults, which is what happens when you use pointers and you should not. In this case, it's probably due to the declaration of p_timespec; I have actually declared it as a CPointer, although the struct should be OK. However, from the segmentation fault I can't fathom what's really wrong. Can someone help?

like image 438
jjmerelo Avatar asked Apr 24 '18 09:04

jjmerelo


1 Answers

There's two things wrong here.

  1. The CStruct representation should be used
  2. You need to make an instance of the structure for it to fill out with data, otherwise you're passing a null pointer

This seems to work:

use NativeCall;

class p_timespec is repr('CStruct') {
    has uint32 $.tv_sec;
    has long $.tv_nanosecs;
}

sub clock_gettime(uint32 $clock-id, p_timespec $tspec --> uint32) is native(Str) { * };

my p_timespec $this-time .= new;

my $result = clock_gettime( 0, $this-time);

say "$result, $this-time.tv_sec(), $this-time.tv_nanosecs()";

As for debugging, Rakudo's installation process also installs a perl6-gdb-m and a perl6-valgrind-m; the latter, while slow, will tend to provide some useful information on memory errors.

like image 130
Jonathan Worthington Avatar answered Oct 14 '22 12:10

Jonathan Worthington