| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Go Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style | |
| 3 // license that can be found in the LICENSE file. | |
| 4 | |
| 5 /* | |
| 6 Gobind generates language bindings that make it possible to call Go code | |
| 7 and pass objects from Java. | |
| 8 | |
| 9 Using gobind | |
| 10 | |
| 11 Gobind takes a Go package and generates bindings for all of the exported | |
| 12 symbols. The exported symbols define the cross-language interface. | |
| 13 | |
| 14 The gobind tool generates both an API stub in Java, and binding code in | |
| 15 Go. Start with a Go package: | |
| 16 | |
| 17 package hi | |
| 18 | |
| 19 import "fmt" | |
| 20 | |
| 21 func Hello(name string) { | |
| 22 fmt.Println("Hello, %s!\n", name) | |
| 23 } | |
| 24 | |
| 25 Generate a Go binding package and Java stubs: | |
| 26 | |
| 27 go install golang.org/x/mobile/cmd/gobind | |
| 28 gobind -lang=go github.com/crawshaw/hi > hi/go_hi/go_hi.go | |
| 29 gobind -lang=java github.com/crawshaw/hi > hi/Hi.java | |
| 30 | |
| 31 The generated Go package, go_hi, must be linked into your Go program: | |
| 32 | |
| 33 import _ "github.com/crawshaw/hi/go_hi" | |
| 34 | |
| 35 Type restrictions | |
| 36 | |
| 37 At present, only a subset of Go types are supported. | |
| 38 | |
| 39 All exported symbols in the package must have types that are supported. | |
| 40 Supported types include: | |
| 41 | |
| 42 - Signed integer and floating point types. | |
| 43 | |
| 44 - String and boolean types. | |
| 45 | |
| 46 - Any function type all of whose parameters and results have | |
| 47 supported types. Functions must return either no results, | |
| 48 one result, or two results where the type of the second is | |
| 49 the built-in 'error' type. | |
| 50 | |
| 51 - Any interface type, all of whose exported methods have | |
| 52 supported function types. | |
| 53 | |
| 54 - Any struct type, all of whose exported methods have | |
| 55 supported function types and all of whose exported fields | |
| 56 have supported types. | |
| 57 | |
| 58 Unexported symbols have no effect on the cross-language interface, and | |
| 59 as such are not restricted. | |
| 60 | |
| 61 The set of supported types will eventually be expanded to cover all Go | |
| 62 types, but this is a work in progress. | |
| 63 | |
| 64 Exceptions and panics are not yet supported. If either pass a language | |
| 65 boundary, the program will exit. | |
| 66 | |
| 67 Passing Go objects to foreign languages | |
| 68 | |
| 69 Consider a type for counting: | |
| 70 | |
| 71 package mypkg | |
| 72 | |
| 73 type Counter struct { | |
| 74 Value int | |
| 75 } | |
| 76 | |
| 77 func (c *Counter) Inc() { c.Value++ } | |
| 78 | |
| 79 func New() *Counter { return &Counter{ 5 } } | |
| 80 | |
| 81 The generated bindings enable Java programs to create and use a Counter. | |
| 82 | |
| 83 public abstract class Mypkg { | |
| 84 private Mypkg() {} | |
| 85 public static final class Counter { | |
| 86 public void Inc() { ... } | |
| 87 public long GetValue() { ... } | |
| 88 public void SetValue(long value) { ... } | |
| 89 } | |
| 90 public static Counter New() { ... } | |
| 91 } | |
| 92 | |
| 93 The package-level function New can be called like so: | |
| 94 | |
| 95 Counter c = Mypkg.New() | |
| 96 | |
| 97 returns a Java Counter, which is a proxy for a Go *Counter. Calling the Inc | |
| 98 and Get methods will call the Go implementations of these methods. | |
| 99 | |
| 100 Passing foreign language objects to Go | |
| 101 | |
| 102 For a Go interface: | |
| 103 | |
| 104 package myfmt | |
| 105 | |
| 106 type Printer interface { | |
| 107 Print(s string) | |
| 108 } | |
| 109 | |
| 110 func PrintHello(p Printer) { | |
| 111 p.Print("Hello, World!") | |
| 112 } | |
| 113 | |
| 114 gobind generates a Java stub that can be used to implement a Printer: | |
| 115 | |
| 116 public abstract class Myfmt { | |
| 117 private Myfmt() {} | |
| 118 public interface Printer { | |
| 119 public void Print(String s); | |
| 120 | |
| 121 public static abstract class Stub implements Printer { | |
| 122 ... | |
| 123 } | |
| 124 | |
| 125 ... | |
| 126 } | |
| 127 | |
| 128 public static void PrintHello(Printer p) { ... } | |
| 129 } | |
| 130 | |
| 131 You can extend Myfmt.Printer.Stub to implement the Printer interface, and | |
| 132 pass it to Go using the PrintHello package function: | |
| 133 | |
| 134 public class SysPrint extends Myfmt.Printer.Stub { | |
| 135 public void Print(String s) { | |
| 136 System.out.println(s); | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 The Java implementation can be used like so: | |
| 141 | |
| 142 Myfmt.Printer printer = new SysPrint(); | |
| 143 Myfmt.PrintHello(printer); | |
| 144 | |
| 145 Avoid reference cycles | |
| 146 | |
| 147 The language bindings maintain a reference to each object that has been | |
| 148 proxied. When a proxy object becomes unreachable, its finalizer reports | |
| 149 this fact to the object's native side, so that the reference can be | |
| 150 removed, potentially allowing the object to be reclaimed by its native | |
| 151 garbage collector. The mechanism is symmetric. | |
| 152 | |
| 153 However, it is possible to create a reference cycle between Go and | |
| 154 Java objects, via proxies, meaning objects cannot be collected. This | |
| 155 causes a memory leak. | |
| 156 | |
| 157 For example, if a Go object G holds a reference to the Go proxy of a | |
| 158 Java object J, and J holds a reference to the Java proxy of G, then the | |
| 159 language bindings on each side must keep G and J live even if they are | |
| 160 otherwise unreachable. | |
| 161 | |
| 162 We recommend that implementations of foreign interfaces do not hold | |
| 163 references to proxies of objects. That is: if you extend a Stub in | |
| 164 Java, do not store an instance of Seq.Object inside it. | |
| 165 | |
| 166 Further reading | |
| 167 | |
| 168 Examples can be found in http://golang.org/x/mobile/example. | |
| 169 | |
| 170 Design doc: http://golang.org/s/gobind | |
| 171 */ | |
| 172 package main // import "golang.org/x/mobile/cmd/gobind" | |
| OLD | NEW |