tree: 0cc5b2330b445979c5259f4e2cd3cb124543257e [path history] [tgz]
  1. refmap/
  2. .gitignore
  3. impl.go
  4. jni.go
  5. jni_lib.go
  6. jni_types.go
  7. jni_util.go
  8. jni_wrapper.c
  9. jni_wrapper.h
  10. jni_wrapper_android.c
  11. jni_wrapper_native.c
  12. lib.h
  13. main.go
  14. Makefile
  15. README.md
  16. types.go
services/syncbase/bridge/cgo/README.md

Syncbase cgo bridge

The Syncbase cgo bridge exposes a C API to Syncbase. It's intended to be used on iOS (Swift) and Android (Java), and perhaps elsewhere as well.

For the time being, we provide a Makefile to build C archives for all target platforms. Eventually, we'll integrate C archive compilation with the jiri tool.

JNI

Java expects functions that have names and arguments that match the native declarations from the .java files located in java/io/v/syncbase/internal.

Layout:

  • jni.go: the JNI functions expected by Java.
  • jni_util.go: helper functions to find Java classes and retrieve IDs for object fields and methods.
  • jni_lib.go: types and functions to cache the field and method IDs for all the classes the code needs to touch.
  • jni_types.go: methods and functions to convert between Java and the types declared in lib.h; counterpart of types.go.
  • jni_wrapper.{h,c}: trampoline functions that compensate for the fact that Go cannot call a function pointer.

Some design notes:

  • looking up classes/interfaces, methods and field IDs is expensive. The global variables named like fooClass from jni.go cache all we need for a class foo. The load is done in JNI_OnLoad, a function that is called each time the our library is loaded (typically, using System.loadLibrary()).
  • some of the extractToJava() methods and newVFoo() functions are in jni.go instead of jni_types.go to avoid some “inconsistent definitions” errors.
  • the extractToJava() methods convert from low-level types like v23_syncbase_Foo to their Java equivalents. The extract() methods convert to Go equivalents. Both extract() and extractToJava() will free all the pointers inside the primitive types they are extracting from.
  • the free() methods are idempotent.
  • we use panic() to enforce certain invariants (enough memory, existence of classes, methods, fields, etc) and to keep the code simple.