FFI::Platypus::Lang::Go - Documentation and tools for using Platypus with Go
version 0.03
Go code:
package main import "C" //export add func add(x, y int) int { return x + y } func main() {}
Perl code:
use FFI::Platypus 2.00; use FFI::CheckLib qw( find_lib_or_die ); use File::Basename qw( dirname ); my $ffi = FFI::Platypus->new( api => 2, lib => './add.so', lang => 'Go', ); $ffi->attach( add => ['goint', 'goint'] => 'goint' ); print add(1,2), "\n"; # prints 3
This distribution is the Go language plugin for Platypus. It provides the definition for native Go types, like goint
and gostring
. It also provides a FFI::Build interface for building Perl extensions written in Go (see FFI::Build::File::GoMod for details).
The examples in this discussion are bundled with this distribution and can be found in the examples
directory.
package main import "C" //export add func add(x, y int) int { return x + y } func main() {}
use FFI::Platypus 2.00; use FFI::CheckLib qw( find_lib_or_die ); use File::Basename qw( dirname ); my $ffi = FFI::Platypus->new( api => 2, lib => './add.so', lang => 'Go', ); $ffi->attach( add => ['goint', 'goint'] => 'goint' ); print add(1,2), "\n"; # prints 3
$ go build -o add.so -buildmode=c-shared add.go $ perl add.pl 3
The Go code has to:
"C"
//export
main
function, even if you do not use it.From the Perl side, the Go types have a go
prefix, so int
in Go is goint
in Perl.
Aside from that passing basic types like integers and floats is trivial with FFI.
/* * borrowed from * https://medium.com/learning-the-go-programming-language/calling-go-functions-from-other-languages-4c7d8bcc69bf */ package main import "C" import ( "fmt" "math" "sort" "sync" ) var count int var mtx sync.Mutex //export Add func Add(a, b int) int { return a + b } //export Cosine func Cosine(x float64) float64 { return math.Cos(x) } //export Sort func Sort(vals []int) { sort.Ints(vals) } //export Log func Log(msg string) int { mtx.Lock() defer mtx.Unlock() fmt.Println(msg) count++ return count } func main() {}
Module:
package Awesome::FFI; use strict; use warnings; use FFI::Platypus; use FFI::Go::String; use base qw( Exporter ); our @EXPORT_OK = qw( Add Cosine Log ); my $ffi = FFI::Platypus->new( api => 1, lang => 'Go' ); # See FFI::Platypus::Bundle for the how and why # bundle works. $ffi->bundle; $ffi->attach( Add => ['goint','goint'] => 'goint' ); $ffi->attach( Cosine => ['gofloat64' ] => 'gofloat64' ); $ffi->attach( Log => ['gostring' ] => 'goint' ); 1;
Test:
use Test2::V0 -no_srand => 1; use Awesome::FFI qw( Add Cosine Log ); use Capture::Tiny qw( capture ); use FFI::Go::String; is( Add(1,2), 3 ); is( Cosine(0), 1.0 ); is( [capture { Log("Hello Perl!") }], ["Hello Perl!\n", '', 1] ); done_testing;
$ prove -lvm t/awesome_ffi.t t/awesome_ffi.t .. ok 1 ok 2 ok 3 1..3 ok All tests successful. Files=1, Tests=3, 1 wallclock secs ( 0.01 usr 0.00 sys + 1.28 cusr 0.48 csys = 1.77 CPU) Result: PASS
This is a full working example of a Perl distribution / module included in the examples/Awesome-FFI
directory.
More about FFI and Platypus itself.
Type plugin for the go string type.
Low level interface to the go string type.
FFI::Build class for handling Go modules.
Author: Graham Ollis <plicease@cpan.org>
Contributors:
Graham TerMarsch (GTERMARS)
This software is copyright (c) 2018-2022 by Graham Ollis.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.