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/CAOyqgcXiL6%2Bm_HtF0SYuExy2Bu9_o%2B3pVAt-FCG3WX05zUOb1A%40mail.gmail.com.