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.

Reply via email to