| a | b | |
|---|
| 0 | + | #! /usr/bin/env perl6 |
|---|
| 0 | + | |
|---|
| 0 | + | use v6; |
|---|
| 0 | + | |
|---|
| 0 | + | use NativeCall; |
|---|
| 0 | + | |
|---|
| 0 | + | class Foo { |
|---|
| 0 | + | has OpaquePointer $!repr; |
|---|
| 0 | + | |
|---|
| 0 | + | sub make_foo() returns OpaquePointer |
|---|
| 0 | + | is native('libstandalone.dylib') {} |
|---|
| 0 | + | sub destroy_foo(OpaquePointer) |
|---|
| 0 | + | is native('libstandalone.dylib') {} |
|---|
| 0 | + | sub foo_getx(OpaquePointer) returns int |
|---|
| 0 | + | is native('libstandalone.dylib') {} |
|---|
| 0 | + | sub foo_setx(OpaquePointer, int) |
|---|
| 0 | + | is native('libstandalone.dylib') {} |
|---|
| 0 | + | |
|---|
| 0 | + | submethod BUILD() { |
|---|
| 0 | + | $!repr = make_foo(); |
|---|
| 0 | + | } |
|---|
| 0 | + | method end() { |
|---|
| 0 | + | destroy_foo($!repr); |
|---|
| 0 | + | } |
|---|
| 0 | + | |
|---|
| 0 | + | method get() { return foo_getx($!repr); } |
|---|
| 0 | + | method set(Int $val) { foo_setx($!repr, $val); } |
|---|
| 0 | + | |
|---|
| 0 | + | method x() is rw { |
|---|
| 0 | + | my $foo := $!repr; |
|---|
| 0 | + | return Proxy.new: |
|---|
| 0 | + | FETCH => method () { |
|---|
| 0 | + | # Change this to $foo instead of $!repr, and it works |
|---|
| 0 | + | return foo_getx($!repr); |
|---|
| 0 | + | }, |
|---|
| 0 | + | STORE => method ($val) { |
|---|
| 0 | + | foo_setx($foo, $val); |
|---|
| 0 | + | }; |
|---|
| 0 | + | } |
|---|
| 0 | + | } |
|---|
| 0 | + | |
|---|
| 0 | + | sub MAIN() { |
|---|
| 0 | + | my $foo = Foo.new; |
|---|
| 0 | + | say "1: ", $foo.x; |
|---|
| 0 | + | $foo.x = 42; |
|---|
| 0 | + | say "2: ", $foo.x; |
|---|
| 0 | + | $foo.end; |
|---|
| 0 | + | say "Done."; |
|---|
| 0 | + | } |
|---|
| 0 | + | |
|---|
| 0 | + | # vim:set ft=perl6: |
|---|
| 0 | + | |
|---|
| 0 | + | |
|---|
| 0 | + | |
|---|
| 0 | + | |
|---|
| 0 | + | #include <assert.h> |
|---|
| 0 | + | #include <stdlib.h> |
|---|
| 0 | + | |
|---|
| 0 | + | /* |
|---|
| 0 | + | Stand-alone test case for segfault w/ NativeCall (tested w/ Rakudo* 2012.06) |
|---|
| 0 | + | |
|---|
| 0 | + | On OS X, compile and link with: |
|---|
| 0 | + | gcc -c standalone.c && libtool -dynamic -o libstandalone.dylib standalone.o |
|---|
| 0 | + | */ |
|---|
| 0 | + | |
|---|
| 0 | + | struct Foo { |
|---|
| 0 | + | int x; |
|---|
| 0 | + | }; |
|---|
| 0 | + | |
|---|
| 0 | + | int foo_getx(struct Foo *foo) { |
|---|
| 0 | + | return foo->x; |
|---|
| 0 | + | } |
|---|
| 0 | + | |
|---|
| 0 | + | void foo_setx(struct Foo *foo, int x) { |
|---|
| 0 | + | foo->x = x; |
|---|
| 0 | + | } |
|---|
| 0 | + | |
|---|
| 0 | + | struct Foo *make_foo(void) { |
|---|
| 0 | + | struct Foo *foo = (struct Foo *)malloc(sizeof(struct Foo)); |
|---|
| 0 | + | foo->x = 0; |
|---|
| 0 | + | } |
|---|
| 0 | + | |
|---|
| 0 | + | void destroy_foo(struct Foo *foo) { |
|---|
| 0 | + | assert(foo != NULL && "destroy_foo(NULL)"); |
|---|
| 0 | + | |
|---|
| 0 | + | free(foo); |
|---|
| 0 | + | } |
|---|
| ... | |
|---|