Thanks Ian, Yes i followed a similar approach and it's working fine.. On Sun, May 19, 2024 at 4:36 AM Ian Lance Taylor <i...@golang.org> wrote:
> On Thu, May 16, 2024 at 12:57 AM Pavan <sudarshan...@gmail.com> wrote: > > > > 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. > > In C, unlike Go, you can convert between void* and uintptr_t. When > using cgo, one approach is a little wrapper function in the cgo > comment that takes a uintptr_t and calls the real function with a > conversion to void*. > > Ian > > > 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 > . > -- 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/CAHJvL%3DYoTFAZ4o8Ep7%2Bgt7B5R82QY9JLEpCCqsBbFezHFHtdWg%40mail.gmail.com.