github.com/SahandAslani/gomobile@v0.0.0-20210909130135-2cb2d44c09b2/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/SahandAslani/gomobile/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 NewCounter() *Counter { return &Counter{ 5 } } 40 41 In Java, the generated bindings are, 42 43 public abstract class Mypkg { 44 public static native Counter newCounter(); 45 } 46 47 and 48 49 public final class Counter { 50 public Counter() { ... } 51 52 public final long getValue(); 53 public final void setValue(long v); 54 public void inc(); 55 56 } 57 58 The package-level function newCounter can be called like so: 59 60 Counter c = Mypkg.newCounter() 61 62 For convenience, functions on the form NewT(...) *T are converted to constructors for T: 63 64 Counter c = new Counter() 65 66 Both forms returns a Java Counter, which is a proxy for a Go *Counter. Calling the inc, getValue and 67 setValue methods will call the Go implementations of these methods. 68 69 Similarly, the same Go package will generate the Objective-C interface 70 71 @class GoMypkgCounter; 72 73 @interface GoMypkgCounter : NSObject { 74 } 75 76 @property(strong, readonly) id ref; 77 - (void)inc; 78 - (int64_t)value; 79 - (void)setValue:(int64_t)v; 80 @end 81 82 FOUNDATION_EXPORT GoMypkgCounter* GoMypkgNewCounter(void); 83 84 The equivalent of calling newCounter in Go is GoMypkgNewCounter in Objective-C. 85 The returned GoMypkgCounter* holds a reference to an underlying Go 86 *Counter. 87 88 Passing target language objects to Go 89 90 For a Go interface: 91 92 package myfmt 93 94 type Printer interface { 95 Print(s string) 96 } 97 98 func PrintHello(p Printer) { 99 p.Print("Hello, World!") 100 } 101 102 gobind generates a Java interface that can be used to implement a Printer: 103 104 public abstract class Myfmt { 105 public static void printHello(Printer p0); 106 } 107 108 and 109 110 public interface Printer { 111 public void print(String s); 112 } 113 114 You can implement Printer, and pass it to Go using the printHello 115 package function: 116 117 public class SysPrint implements Printer { 118 public void print(String s) { 119 System.out.println(s); 120 } 121 } 122 123 The Java implementation can be used like so: 124 125 Printer printer = new SysPrint(); 126 Myfmt.printHello(printer); 127 128 129 For Objective-C binding, gobind generates a protocol that declares 130 methods corresponding to Go interface's methods. 131 132 @protocol GoMyfmtPrinter 133 - (void)Print:(NSString*)s; 134 @end 135 136 FOUNDATION_EXPORT void GoMyfmtPrintHello(id<GoMyfmtPrinter> p0); 137 138 Any Objective-C classes conforming to the GoMyfmtPrinter protocol can be 139 passed to Go using the GoMyfmtPrintHello function: 140 141 @interface SysPrint : NSObject<GoMyfmtPrinter> { 142 } 143 @end 144 145 @implementation SysPrint { 146 } 147 - (void)Print:(NSString*)s { 148 NSLog("%@", s); 149 } 150 @end 151 152 The Objective-C implementation can be used like so: 153 154 SysPrint* printer = [[SysPrint alloc] init]; 155 GoMyfmtPrintHello(printer); 156 157 158 Type restrictions 159 160 At present, only a subset of Go types are supported. 161 162 All exported symbols in the package must have types that are supported. 163 Supported types include: 164 165 - Signed integer and floating point types. 166 167 - String and boolean types. 168 169 - Byte slice types. Note that byte slices are passed by reference, 170 and support mutation. 171 172 - Any function type all of whose parameters and results have 173 supported types. Functions must return either no results, 174 one result, or two results where the type of the second is 175 the built-in 'error' type. 176 177 - Any interface type, all of whose exported methods have 178 supported function types. 179 180 - Any struct type, all of whose exported methods have 181 supported function types and all of whose exported fields 182 have supported types. 183 184 Unexported symbols have no effect on the cross-language interface, and 185 as such are not restricted. 186 187 The set of supported types will eventually be expanded to cover more 188 Go types, but this is a work in progress. 189 190 Exceptions and panics are not yet supported. If either pass a language 191 boundary, the program will exit. 192 193 194 Reverse bindings 195 196 Gobind also supports accessing API from Java or Objective C from Go. 197 Similar to how Cgo supports the magic "C" import, gobind recognizes 198 import statements that start with "Java/" or "ObjC/". For example, 199 to import java.lang.System and call the static method currentTimeMillis: 200 201 import "Java/java/lang/System" 202 203 t := System.CurrentTimeMillis() 204 205 Similarly, to import NSDate and call the static method [NSDate date]: 206 207 import "ObjC/Foundation/NSDate" 208 209 d := NSDate.Date() 210 211 Gobind also supports specifying particular classes, interfaces or 212 protocols a particular Go struct should extend or implement. For example, 213 to create an Android Activity subclass MainActivity: 214 215 import "Java/android/app/Activity" 216 217 type MainActivity struct { 218 app.Activity 219 } 220 221 Gobind also recognizes Java interfaces as well as Objective C classes and 222 protocols the same way. 223 224 For more details on binding the the native API, see the design proposals, 225 https://golang.org/issues/16876 (Java) and https://golang.org/issues/17102 226 (Objective C). 227 228 Avoid reference cycles 229 230 The language bindings maintain a reference to each object that has been 231 proxied. When a proxy object becomes unreachable, its finalizer reports 232 this fact to the object's native side, so that the reference can be 233 removed, potentially allowing the object to be reclaimed by its native 234 garbage collector. The mechanism is symmetric. 235 236 However, it is possible to create a reference cycle between Go and 237 objects in target languages, via proxies, meaning objects cannot be 238 collected. This causes a memory leak. 239 240 For example, in Java: if a Go object G holds a reference to the Go 241 proxy of a Java object J, and J holds a reference to the Java proxy 242 of G, then the language bindings on each side must keep G and J live 243 even if they are otherwise unreachable. 244 245 We recommend that implementations of foreign interfaces do not hold 246 references to proxies of objects. That is: if you implement a Go 247 interface in Java, do not store an instance of Seq.Object inside it. 248 249 Further reading 250 251 Examples can be found in http://github.com/SahandAslani/gomobile/example. 252 253 Design doc: http://golang.org/s/gobind 254 */ 255 package main // import "github.com/SahandAslani/gomobile/cmd/gobind"