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"