cgo类型相当于指向结构的常量指针是什么?
我在cgo类型相当于指向结构的常量指针是什么?,go,cgo,Go,Cgo,我在C中标记了一个外部函数: //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/lib
C
中标记了一个外部函数:
//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
与const struct libvlc\u event.*
等效的是什么?使用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")
}
如果您想知道与C.clibvlc_event_t
兼容的go
类型定义,请使用-godefs
选项运行cgo
,即
go tool cgo -godefs <YOUR-GO-FILE>
然后,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{}))
编辑:添加示例结构。编译器会抱怨,因为函数
goCallback
在C
和Go
中都定义了。当您想从C
访问go
功能时,需要使用//导出…
。如果你想从go
使用C
函数,//外部无效…
就足够了。看看,我做得对,从C
访问go
需要//外部声明
和//导出注释
。对不起,我误解了你的问题。编译器抱怨,因为有两个签名不同的goCallback
函数。我写了一个答案,希望能有帮助。谢谢你的回答,我只是想知道为什么我应该把libvlc_event_t
化名为clibvlc_event_t
?@tarsalah实际上,如果参数没有const
限定符,你可以通过C.struct\libvlc_event_t
访问C
结构。由于go
没有const
限定符,typedef
是一种解决方法。在这里,我选择clibvlc\u event\t
表示该类型具有const
限定符。您可以使用libvlc\u event\t
。另一个解决方案是在C
中创建另一个回调函数,而不使用const
限定符。您的回答和评论非常有用,谢谢。
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{}))