// transact calls a method on an Objective-C object instance. // It blocks until the call is complete. // // Code (>0) is the method id assigned by gobind. // Code -1 is used to instruct Objective-C to decrement the ref count of // the Objective-Co object. func transact(ref *seq.Ref, descriptor string, code int, in *seq.Buffer) *seq.Buffer { var ( res *C.uint8_t = nil resLen C.size_t = 0 req *C.uint8_t = nil reqLen C.size_t = 0 ) if len(in.Data) > 0 { req = (*C.uint8_t)(unsafe.Pointer(&in.Data[0])) reqLen = C.size_t(len(in.Data)) } if debug { fmt.Printf("transact: ref.Num = %d code = %d\n", ref.Num, code) } desc := cstrings.get(descriptor) C.go_seq_recv(C.int32_t(ref.Num), desc, C.int(code), req, reqLen, &res, &resLen) if resLen > 0 { goSlice := (*[maxSliceLen]byte)(unsafe.Pointer(res))[:resLen] out := new(seq.Buffer) out.Data = make([]byte, int(resLen)) copy(out.Data, goSlice) C.free(unsafe.Pointer(res)) // TODO: own or copy []bytes whose addresses were passed in. return out } return nil }
// Send is called by Java to send a request to run a Go function. //export Send func Send(descriptor string, code int, req *C.uint8_t, reqlen C.size_t, res **C.uint8_t, reslen *C.size_t) { fn := seq.Registry[descriptor][code] in := new(seq.Buffer) if reqlen > 0 { in.Data = (*[maxSliceLen]byte)(unsafe.Pointer(req))[:reqlen] } out := new(seq.Buffer) fn(out, in) seqToBuf(res, reslen, out) }
// Send is called by Java to send a request to run a Go function. //export Send func Send(descriptor string, code int, req *C.uint8_t, reqlen C.size_t, res **C.uint8_t, reslen *C.size_t) { fn := seq.Registry[descriptor][code] if fn == nil { panic(fmt.Sprintf("invalid descriptor(%s) and code(0x%x)", descriptor, code)) } in := new(seq.Buffer) if reqlen > 0 { in.Data = (*[maxSliceLen]byte)(unsafe.Pointer(req))[:reqlen] } out := new(seq.Buffer) fn(out, in) // BUG(hyangah): the function returning a go byte slice (so fn writes a pointer into 'out') is unsafe. // After fn is complete here, Go runtime is free to collect or move the pointed byte slice // contents. (Explicitly calling runtime.GC here will surface the problem?) // Without pinning support from Go side, it will be hard to fix it without extra copying. seqToBuf(res, reslen, out) }