github.com/adwpc/xmobile@v0.0.0-20231212131043-3f9720cf0e99/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/adwpc/xmobile/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  For Objective-C binding, gobind generates a protocol that declares
   129  methods corresponding to Go interface's methods.
   130  
   131  	@protocol GoMyfmtPrinter
   132  	- (void)Print:(NSString*)s;
   133  	@end
   134  
   135  	FOUNDATION_EXPORT void GoMyfmtPrintHello(id<GoMyfmtPrinter> p0);
   136  
   137  Any Objective-C classes conforming to the GoMyfmtPrinter protocol can be
   138  passed to Go using the GoMyfmtPrintHello function:
   139  
   140  	@interface SysPrint : NSObject<GoMyfmtPrinter> {
   141  	}
   142  	@end
   143  
   144  	@implementation SysPrint {
   145  	}
   146  	- (void)Print:(NSString*)s {
   147  		NSLog("%@", s);
   148  	}
   149  	@end
   150  
   151  The Objective-C implementation can be used like so:
   152  
   153  	SysPrint* printer = [[SysPrint alloc] init];
   154  	GoMyfmtPrintHello(printer);
   155  
   156  # Type restrictions
   157  
   158  At present, only a subset of Go types are supported.
   159  
   160  All exported symbols in the package must have types that are supported.
   161  Supported types include:
   162  
   163    - Signed integer and floating point types.
   164  
   165    - String and boolean types.
   166  
   167    - Byte slice types. Note that byte slices are passed by reference,
   168      and support mutation.
   169  
   170    - Any function type all of whose parameters and results have
   171      supported types. Functions must return either no results,
   172      one result, or two results where the type of the second is
   173      the built-in 'error' type.
   174  
   175    - Any interface type, all of whose exported methods have
   176      supported function types.
   177  
   178    - Any struct type, all of whose exported methods have
   179      supported function types and all of whose exported fields
   180      have supported types.
   181  
   182  Unexported symbols have no effect on the cross-language interface, and
   183  as such are not restricted.
   184  
   185  The set of supported types will eventually be expanded to cover more
   186  Go types, but this is a work in progress.
   187  
   188  Exceptions and panics are not yet supported. If either pass a language
   189  boundary, the program will exit.
   190  
   191  # Reverse bindings
   192  
   193  Gobind also supports accessing API from Java or Objective C from Go.
   194  Similar to how Cgo supports the magic "C" import, gobind recognizes
   195  import statements that start with "Java/" or "ObjC/". For example,
   196  to import java.lang.System and call the static method currentTimeMillis:
   197  
   198  	import "Java/java/lang/System"
   199  
   200  	t := System.CurrentTimeMillis()
   201  
   202  Similarly, to import NSDate and call the static method [NSDate date]:
   203  
   204  	import "ObjC/Foundation/NSDate"
   205  
   206  	d := NSDate.Date()
   207  
   208  Gobind also supports specifying particular classes, interfaces or
   209  protocols a particular Go struct should extend or implement. For example,
   210  to create an Android Activity subclass MainActivity:
   211  
   212  	import "Java/android/app/Activity"
   213  
   214  	type MainActivity struct {
   215  		app.Activity
   216  	}
   217  
   218  Gobind also recognizes Java interfaces as well as Objective C classes and
   219  protocols the same way.
   220  
   221  For more details on binding the native API, see the design proposals,
   222  https://golang.org/issues/16876 (Java) and https://golang.org/issues/17102
   223  (Objective C).
   224  
   225  # Avoid reference cycles
   226  
   227  The language bindings maintain a reference to each object that has been
   228  proxied. When a proxy object becomes unreachable, its finalizer reports
   229  this fact to the object's native side, so that the reference can be
   230  removed, potentially allowing the object to be reclaimed by its native
   231  garbage collector.  The mechanism is symmetric.
   232  
   233  However, it is possible to create a reference cycle between Go and
   234  objects in target languages, via proxies, meaning objects cannot be
   235  collected. This causes a memory leak.
   236  
   237  For example, in Java: if a Go object G holds a reference to the Go
   238  proxy of a Java object J, and J holds a reference to the Java proxy
   239  of G, then the language bindings on each side must keep G and J live
   240  even if they are otherwise unreachable.
   241  
   242  We recommend that implementations of foreign interfaces do not hold
   243  references to proxies of objects. That is: if you implement a Go
   244  interface in Java, do not store an instance of Seq.Object inside it.
   245  
   246  # Further reading
   247  
   248  Examples can be found in http://github.com/adwpc/xmobile/example.
   249  
   250  Design doc: http://golang.org/s/gobind
   251  */
   252  package main // import "github.com/adwpc/xmobile/cmd/gobind"