什么是cgo类型等同于指向结构的const指针?
我有一个外部函数decalred在C
:什么是cgo类型等同于指向结构的const指针?
//extern void goCallback(const struct libvlc_event_t*, void*);
要go
定义:
//export goCallback
func goCallback(event unsafe.Pointer, userData unsafe.Pointer) {
log.Fatal("TODO goCallback")
}
当编译代码时,我得到类型冲突的错误
# 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*);
^~~~~~~~~~
是什么go
相当于3210?
与typedef
创建类型别名的结构如下:
/*
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")
}
如果你想知道go
类型定义,它是C.clibvlc_event_t
兼容,运行cgo
与-godefs
选项,即
go tool cgo -godefs <YOUR-GO-FILE>
例如,如果结构被定义为如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;
};
然后,在go
兼容结构将是:
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{}))
编辑:
添加示例结构。
感谢您的回答,我只是想知道为什么要将'libvlc_event_t'别名到'clibvlc_event_t'? – tarrsalah
@tarrsalah实际上,如果参数没有'const'限定符,则可以通过'C.struct_libvlc_event_t'访问'C'结构。由于'go'没有'const'限定符,'typedef'是一种解决方法。在这里,我选择'clibvlc_event_t'来表示这个类型具有'const'限定符。你可以使用'libvlc_event_t'。另一种解决方法是在'C'中创建另一个没有const限定符的回调函数。 – putu
您的回答和您的意见非常有帮助,谢谢。 – tarrsalah
编译器抱怨,因为在'C'和'Go'中都定义了'goCallback'函数。当你希望你的'go'函数可以从'C'访问时,需要'// export ...'。如果你想从'go'使用'C'功能,'// extern void ...'就足够了。 – putu
看一下https://github.com/golang/go/wiki/cgo#function-variables,我做得很对,从'c'访问'go'需要'// extern声明'和'//注释'。 – tarrsalah
对不起,我误解了你的问题。编译器抱怨,因为有两个具有不同签名的'goCallback'函数。我写了一个答案,希望它有帮助。 – putu