Thanks . Yes it works when C API takes uintptr_t. In my case, the C API expects void * which i can not change, so I was trying to make it work with the variant example stated above.
On Thursday, May 16, 2024 at 5:28:55 AM UTC+5:30 Ian Lance Taylor wrote: > On Tue, May 14, 2024 at 10:37 PM Pavan <sudars...@gmail.com> wrote: > > > > I need to pass value of struct type, which has C strings and functions > to C function as void* argument. C layer would provide this struct type > data back to go function. Below is the sample program. It panics if the > handle used is returned from getH function. It works fine if the handle is > global. Can the handle be dynamically returned from getH and make it work. > Please correct if i missed something.. > > > > > > > > package main > > > > /* > > struct dt { > > void *context; > > }; > > typedef struct dt dt; > > > > extern void MyGoPrint(void *context); > > static inline void myprint(struct dt *a1) { > > MyGoPrint(a1->context); > > } > > */ > > import "C" > > import ( > > "context" > > "runtime/cgo" > > "unsafe" > > ) > > > > //export MyGoPrint > > func MyGoPrint(context unsafe.Pointer) { > > h := *(*cgo.Handle)(context) > > val := h.Value().(accessTokenCB) > > println(val.id) > > h.Delete() > > } > > > > type At struct { > > Tok string > > } > > > > type accessTokenCB struct { > > ctx context.Context > > callback func(context.Context, *At) error > > id uint64 > > ctoken *C.char > > cprivateKey *C.char > > } > > > > func getH() cgo.Handle { > > cb := func(ctx context.Context, tok *At) error { > > tok.Tok = "123" > > return nil > > } > > val := accessTokenCB{callback: cb, ctx: context.Background(), id: 32, > ctoken: nil, cprivateKey: nil} > > h := cgo.NewHandle(val) > > return h > > > > } > > > > var h cgo.Handle > > > > func main() { > > var h cgo.Handle // commenting this line runs the program successfully > else it panics. (cgo argument has Go pointer to unpinned Go pointer) > > h = getH() > > var poolCt C.dt > > poolCt.context = unsafe.Pointer(&h) > > C.myprint(&poolCt) > > // Output: 32 > > } > > You aren't following the pattern shown at > https://pkg.go.dev/runtime/cgo#Handle. Pass the cgo.Handle value to C > code, not the address of the cgo.Handle value. Catch the cgo.Handle > value as a uintptr_t in C. The point of using cgo.Handle is to avoid > difficulties passing pointers between Go and C. When you pass a > pointer to a cgo.Handle, you just get those difficulties back again. > > Ian > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/39afbb8b-8361-40a2-967f-0f462ef45994n%40googlegroups.com.