github.com/c-darwin/mobile@v0.0.0-20160313183840-ff625c46f7c9/cmd/gobind/doc.go (about) 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 7 functions from Java and Objective-C. 8 9 Typically gobind is not used directly. Instead, a binding is 10 generated and automatically packaged for Android or iOS by 11 `gomobile bind`. For more details on installing and using the gomobile 12 tool, see https://github.com/c-darwin/mobile/cmd/gomobile. 13 14 Binding Go 15 16 Gobind generates target language (Java or Objective-C) bindings for 17 each exported symbol in a Go package. The Go package you choose to 18 bind defines a cross-language interface. 19 20 Bindings require additional Go code be generated, so using gobind 21 manually requires calling it twice, first with -lang=<target>, where 22 target is either java or objc, and again with -lang=go. The generated 23 package can then be _ imported into a Go program, typically built 24 with -buildmode=c-archive for iOS or -buildmode=c-shared for Android. 25 These details are handled by the `gomobile bind` command. 26 27 Passing Go objects to target languages 28 29 Consider a type for counting: 30 31 package mypkg 32 33 type Counter struct { 34 Value int 35 } 36 37 func (c *Counter) Inc() { c.Value++ } 38 39 func New() *Counter { return &Counter{ 5 } } 40 41 In Java, the generated bindings are, 42 43 public abstract class Mypkg { 44 private Mypkg() {} 45 public static final class Counter { 46 public void Inc(); 47 public long GetValue(); 48 public void SetValue(long value); 49 } 50 public static Counter New(); 51 } 52 53 The package-level function New can be called like so: 54 55 Counter c = Mypkg.New() 56 57 returns a Java Counter, which is a proxy for a Go *Counter. Calling the Inc 58 and Get methods will call the Go implementations of these methods. 59 60 Similarly, the same Go package will generate the Objective-C interface 61 62 @class GoMypkgCounter; 63 64 @interface GoMypkgCounter : NSObject { 65 } 66 67 @property(strong, readonly) GoSeqRef *ref; 68 - (void)Inc; 69 - (int64_t)Value; 70 - (void)setValue:(int64_t)v; 71 @end 72 73 FOUNDATION_EXPORT GoMypkgCounter* GoMypkgNewCounter(); 74 75 The equivalent of calling New in Go is GoMypkgNewCounter in Objective-C. 76 The returned GoMypkgCounter* holds a reference to an underlying Go 77 *Counter. 78 79 Passing target language objects to Go 80 81 For a Go interface: 82 83 package myfmt 84 85 type Printer interface { 86 Print(s string) 87 } 88 89 func PrintHello(p Printer) { 90 p.Print("Hello, World!") 91 } 92 93 gobind generates a Java stub that can be used to implement a Printer: 94 95 public abstract class Myfmt { 96 private Myfmt() {} 97 public interface Printer { 98 public void Print(String s); 99 100 public static abstract class Stub implements Printer { 101 ... 102 } 103 104 ... 105 } 106 107 public static void PrintHello(Printer p) { ... } 108 } 109 110 You can extend Myfmt.Printer.Stub to implement the Printer interface, and 111 pass it to Go using the PrintHello package function: 112 113 public class SysPrint extends Myfmt.Printer.Stub { 114 public void Print(String s) { 115 System.out.println(s); 116 } 117 } 118 119 The Java implementation can be used like so: 120 121 Myfmt.Printer printer = new SysPrint(); 122 Myfmt.PrintHello(printer); 123 124 125 For Objective-C binding, gobind generates a protocol that declares 126 methods corresponding to Go interface's methods. 127 128 @protocol GoMyfmtPrinter 129 - (void)Print:(NSString*)s; 130 @end 131 132 FOUNDATION_EXPORT void GoMyfmtPrintHello(id<GoMyfmtPrinter> p0); 133 134 Any Objective-C classes conforming to the GoMyfmtPrinter protocol can be 135 passed to Go using the GoMyfmtPrintHello function: 136 137 @interface SysPrint : NSObject<GoMyfmtPrinter> { 138 } 139 @end 140 141 @implementation SysPrint { 142 } 143 - (void)Print:(NSString*)s { 144 NSLog("%@", s); 145 } 146 @end 147 148 The Objective-C implementation can be used like so: 149 150 SysPrint* printer = [[SysPrint alloc] init]; 151 GoMyfmtPrintHello(printer); 152 153 154 Type restrictions 155 156 At present, only a subset of Go types are supported. 157 158 All exported symbols in the package must have types that are supported. 159 Supported types include: 160 161 - Signed integer and floating point types. 162 163 - String and boolean types. 164 165 - Byte slice types. Note the current implementation does not 166 support data mutation of slices passed in as function arguments. 167 (https://golang.org/issues/12113) 168 169 - Any function type all of whose parameters and results have 170 supported types. Functions must return either no results, 171 one result, or two results where the type of the second is 172 the built-in 'error' type. 173 174 - Any interface type, all of whose exported methods have 175 supported function types. 176 177 - Any struct type, all of whose exported methods have 178 supported function types and all of whose exported fields 179 have supported types. 180 181 Unexported symbols have no effect on the cross-language interface, and 182 as such are not restricted. 183 184 The set of supported types will eventually be expanded to cover more 185 Go types, but this is a work in progress. 186 187 Exceptions and panics are not yet supported. If either pass a language 188 boundary, the program will exit. 189 190 Avoid reference cycles 191 192 The language bindings maintain a reference to each object that has been 193 proxied. When a proxy object becomes unreachable, its finalizer reports 194 this fact to the object's native side, so that the reference can be 195 removed, potentially allowing the object to be reclaimed by its native 196 garbage collector. The mechanism is symmetric. 197 198 However, it is possible to create a reference cycle between Go and 199 objects in target languages, via proxies, meaning objects cannot be 200 collected. This causes a memory leak. 201 202 For example, in Java: if a Go object G holds a reference to the Go 203 proxy of a Java object J, and J holds a reference to the Java proxy 204 of G, then the language bindings on each side must keep G and J live 205 even if they are otherwise unreachable. 206 207 We recommend that implementations of foreign interfaces do not hold 208 references to proxies of objects. That is: if you extend a Stub in 209 Java, do not store an instance of Seq.Object inside it. 210 211 Further reading 212 213 Examples can be found in http://github.com/c-darwin/mobile/example. 214 215 Design doc: http://golang.org/s/gobind 216 */ 217 package main // import "github.com/c-darwin/mobile/cmd/gobind"