Salah Eddine Taouririt
Salah Eddine Taouririt

Reputation: 26445

What is the cgo type equivalent to a const pointer to a struct?

I have an extern function decalred in C:

//extern void goCallback(const struct libvlc_event_t*, void*);

To be defined in go:

//export goCallback
func goCallback(event unsafe.Pointer, userData unsafe.Pointer) {
    log.Fatal("TODO goCallback")
}

When compiling the code, I get type conflicting errors

# github.com/tarrsalah/libvlc-go
In file included from $WORK/github.com/tarrsalah/libvlc-go/_obj/_cgo_export.c:3:0:
cgo-gcc-export-header-prolog:42:13: error: conflicting types for ‘goCallback’
In file included from $WORK/github.com/tarrsalah/libvlc-go/_obj/_cgo_export.c:3:0:
../../../tarrsalah/libvlc-go/event_manager.go:6:13: note: previous declaration of ‘goCallback’ was here
 //extern void goCallback(const struct libvlc_event_t*, void*);
             ^~~~~~~~~~
/tmp/go-build855229382/github.com/tarrsalah/libvlc-go/_obj/_cgo_export.c:17:6: error: conflicting types for ‘goCallback’
 void goCallback(void* p0, void* p1)
      ^~~~~~~~~~
In file included from $WORK/github.com/tarrsalah/libvlc-go/_obj/_cgo_export.c:3:0:
../../../tarrsalah/libvlc-go/event_manager.go:6:13: note: previous declaration of ‘goCallback’ was here
 //extern void goCallback(const struct libvlc_event_t*, void*);
             ^~~~~~~~~~

What is the go equivalent to const struct libvlc_event_t*?

Upvotes: 1

Views: 1480

Answers (1)

putu
putu

Reputation: 6444

Create type alias to the struct with typedef as follows:

/*

typedef const struct libvlc_event_t clibvlc_event_t;
extern void goCallback(clibvlc_event_t*, void*);
*/
import "C"

//export goCallback
func goCallback(event *C.clibvlc_event_t, userData unsafe.Pointer) {
    log.Fatal("TODO goCallback")
}

If you want to know go type definition which is compatible to C.clibvlc_event_t, run cgo with -godefs options, i.e.

go tool cgo -godefs <YOUR-GO-FILE>

For example, if the struct is defined as in https://docs.libreoffice.org/avmedia/html/Types_8hxx_source.html

struct libvlc_event_t
{
    int   type;  // event type
    void *p_obj; // object emitting that event

    union // so far we don't need this.
    {
     struct {
        const char *dummy1;
        const char *dummy2;
      } padding;
    } u;
};

then, the compatible struct in go will be:

type VLCEvent struct {
    Type      int32
    Pad_cgo_0 [4]byte
    Obj       *byte
    U         [16]byte
}

//Cast C struct to Go struct
ev := (*VLCEvent)(unsafe.Pointer(event))

//Cast Go struct to C struct
p := (*C.clibvlc_event_t)(unsafe.Pointer(&VLCEvent{}))

EDIT:
Add example struct.

Upvotes: 3

Related Questions