cgo类型中与指向结构体的常量指针等效的类型是什么?

huangapple go评论110阅读模式
英文:

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

问题

我在C中有一个外部函数声明:

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

go中定义如下:

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

在编译代码时,我遇到了类型冲突错误:

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

go中与const struct libvlc_event_t*等效的是什么?

英文:

I have an extern function decalred in C:

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

To be defined in go:

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

When compiling the code, I get type conflicting errors

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

What is the go equivalent to const struct libvlc_event_t*?

答案1

得分: 2

创建一个使用typedef的结构体类型别名,如下所示:

  1. typedef const struct libvlc_event_t clibvlc_event_t;
  2. extern void goCallback(clibvlc_event_t*, void*);

导入"C"包

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

如果你想知道与C.clibvlc_event_t兼容的go类型定义,可以使用-godefs选项运行cgo,例如:

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

例如,如果结构体定义如下所示:https://docs.libreoffice.org/avmedia/html/Types_8hxx_source.html

  1. struct libvlc_event_t
  2. {
  3. int type; // 事件类型
  4. void *p_obj; // 发出该事件的对象
  5. union // 目前我们不需要这个。
  6. {
  7. struct {
  8. const char *dummy1;
  9. const char *dummy2;
  10. } padding;
  11. } u;
  12. };

那么,在go中兼容的结构体将是:

  1. type VLCEvent struct {
  2. Type int32
  3. Pad_cgo_0 [4]byte
  4. Obj *byte
  5. U [16]byte
  6. }
  7. //将C结构体转换为Go结构体
  8. ev := (*VLCEvent)(unsafe.Pointer(event))
  9. //将Go结构体转换为C结构体
  10. p := (*C.clibvlc_event_t)(unsafe.Pointer(&VLCEvent{}))

编辑:
添加示例结构体。

英文:

Create type alias to the struct with typedef as follows:

  1. /*
  2. typedef const struct libvlc_event_t clibvlc_event_t;
  3. extern void goCallback(clibvlc_event_t*, void*);
  4. */
  5. import &quot;C&quot;
  6. //export goCallback
  7. func goCallback(event *C.clibvlc_event_t, userData unsafe.Pointer) {
  8. log.Fatal(&quot;TODO goCallback&quot;)
  9. }

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

  1. go tool cgo -godefs &lt;YOUR-GO-FILE&gt;

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

  1. struct libvlc_event_t
  2. {
  3. int type; // event type
  4. void *p_obj; // object emitting that event
  5. union // so far we don&#39;t need this.
  6. {
  7. struct {
  8. const char *dummy1;
  9. const char *dummy2;
  10. } padding;
  11. } u;
  12. };

then, the compatible struct in go will be:

  1. type VLCEvent struct {
  2. Type int32
  3. Pad_cgo_0 [4]byte
  4. Obj *byte
  5. U [16]byte
  6. }
  7. //Cast C struct to Go struct
  8. ev := (*VLCEvent)(unsafe.Pointer(event))
  9. //Cast Go struct to C struct
  10. p := (*C.clibvlc_event_t)(unsafe.Pointer(&amp;VLCEvent{}))

EDIT:
Add example struct.

huangapple
  • 本文由 发表于 2017年6月23日 01:37:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/44706042.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定