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.

Reply via email to