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"