Skip to content

Instantly share code, notes, and snippets.

@Xliff
Last active November 7, 2018 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xliff/eb76df40cca74aaa829687ccd1e8e082 to your computer and use it in GitHub Desktop.
Save Xliff/eb76df40cca74aaa829687ccd1e8e082 to your computer and use it in GitHub Desktop.
Blocks, Subs and NativeCall

I have a suib that I'd like to use, like so:

$list.set_sorter(-> $a, $b --> gint {
  %messages{$a}<data><time> <=> %messages{$b}<data><time>
});

set_sorter() is a method on the $list Object that passes the argument to a C-function. It can be summed up as:

method set_sorter (&sort_func) {
  # Do some setup.
  #...
  call_c_code($pointer, &sort_func);
}

The signature of call_c_code() can then impose the signature it wants, and Perl6 should catch any errors. The problem comes at run-time when $list.set_sorter() is invoked:

Native call expected return type with CPointer representation, but got a P6opaque (Block)
  in method CALL-ME at /home/cbwood/Projects/rakudobrew/moar-master/install/share/perl6/sources/947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 581

Well, this type of error may catch many Perl6'ers with a C background. I made the mistake of using the following NativeCall definition:

sub call_c_code (Pointer $sorter)
  is native(gtk)
  is export
  { * }

Now in C, a pointer is all you need, but in Perl6, your NativeCall definition has to be a bit more specific. Redoing the definition as follows allowed the code to work as intended:

sub call_c_code( &sort_func (SortKey, SortKey --> gint) )
  is native(gtk)
  is export
  { * }

Hope this helps others find the solution to their problems!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment