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.

Reply via email to