Golang(cgo)- 支持使用cgo嵌套结构体吗?

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

Golang (cgo) - Support for nested structs with cgo?

问题

我正在尝试使用cgo为x264库编写一个小的包装器,并遇到了嵌套结构的问题。该库使用了许多复杂的结构体,其中一些字段本身就是匿名结构体。

当尝试使用cgo访问这些结构体时,我遇到了编译错误,因为Go声称嵌套结构体不存在。

我已经将问题简化为下面粘贴的.h文件和.go文件。希望这足够清楚地显示问题。

有人知道这个问题的解决方案或变通方法吗?

谢谢。

struct.h

  1. typedef struct param_struct_t {
  2. int a;
  3. int b;
  4. struct {
  5. int c;
  6. int d;
  7. } anon;
  8. int e;
  9. struct {
  10. int f;
  11. int g;
  12. } anon2;
  13. } param_struct_t;

main.go

  1. package main
  2. /*
  3. #include "struct.h"
  4. */
  5. import "C"
  6. import (
  7. "fmt"
  8. )
  9. func main() {
  10. var param C.param_struct_t
  11. fmt.Println(param.a) // 正常工作,应该可以工作
  12. fmt.Println(param.b) // 正常工作,应该可以工作
  13. fmt.Println(param.c) // 正常工作,但不应该可以工作
  14. fmt.Println(param.d) // 正常工作,但不应该可以工作
  15. // fmt.Println(param.e) // 产生类型错误:./main.go:17: param.e undefined (type C.param_struct_t has no field or method e)
  16. // fmt.Println(param.anon) // 产生类型错误:./main.go:18: param.anon undefined (type C.param_struct_t has no field or method anon)
  17. // 下面的代码显示第一个参数和第一个匿名结构体的参数被正确读取,但后续的内容被读取为似乎是原始字节。
  18. fmt.Printf("%#v", param) // 输出:main._Ctype_param_struct_t{a:0, b:0, c:0, d:0, _:[12]uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
  19. }
英文:

I was trying to use cgo to write a little wrapper for the x264 library and came across a problem with nested structs. The library uses a lot of complicated structs where some of the fields are anonymous structs themselves.

When trying to use cgo to access these structs, I run in to compilation errors because go claims that the nested structs do not exist.

I've managed to boil down the problem into a .h file and a .go file pasted below. Hopefully that is clear enough to show the problem.

Does anyone know a solution or workaround to this problem?

Thanks.

struct.h

  1. typedef struct param_struct_t {
  2. int a;
  3. int b;
  4. struct {
  5. int c;
  6. int d;
  7. } anon;
  8. int e;
  9. struct {
  10. int f;
  11. int g;
  12. } anon2;
  13. } param_struct_t;

main.go

  1. package main
  2. /*
  3. #include "struct.h"
  4. */
  5. import "C"
  6. import (
  7. "fmt"
  8. )
  9. func main() {
  10. var param C.param_struct_t
  11. fmt.Println(param.a) // Works and should work
  12. fmt.Println(param.b) // Works and should work
  13. fmt.Println(param.c) // Works fine but shouldn't work
  14. fmt.Println(param.d) // Works fine but shouldn't work
  15. // fmt.Println(param.e) // Produces type error: ./main.go:17: param.e undefined (type C.param_struct_t has no field or method e)
  16. // fmt.Println(param.anon) // Produces type error: ./main.go:18: param.anon undefined (type C.param_struct_t has no field or method anon)
  17. // The following shows that the first parameters and the parameters from the
  18. // first anonymous struct gets read properly, but the subsequent things are
  19. // read as seemingly raw bytes.
  20. fmt.Printf("%#v", param) // Prints out: main._Ctype_param_struct_t{a:0, b:0, c:0, d:0, _:[12]uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
  21. }

答案1

得分: 2

你正在使用哪个版本的Go?使用Go 1.1.2,cgo似乎产生了预期的输出。

我运行了go tool cgo main.go命令,生成的_obj/_cgo_gotypes.go文件包含了以下定义:

  1. type _Ctype_param_struct_t _Ctype_struct_param_struct_t
  2. type _Ctype_struct___0 struct {
  3. //line :1
  4. c _Ctype_int
  5. //line :1
  6. d _Ctype_int
  7. //line :1
  8. }
  9. type _Ctype_struct___1 struct {
  10. //line :1
  11. f _Ctype_int
  12. //line :1
  13. g _Ctype_int
  14. //line :1
  15. }
  16. type _Ctype_struct_param_struct_t struct {
  17. //line :1
  18. a _Ctype_int
  19. //line :1
  20. b _Ctype_int
  21. //line :1
  22. anon _Ctype_struct___0
  23. //line :1
  24. e _Ctype_int
  25. //line :1
  26. anon2 _Ctype_struct___1
  27. //line :1
  28. }

当我修改了你的程序,正确地引用了anon字段中嵌套的cd,并取消了其他语句的注释后,程序编译并运行,最后一条语句打印了结构体:

  1. main._Ctype_param_struct_t{a:0, b:0, anon:main._Ctype_struct___0{c:0, d:0}, e:0, anon2:main._Ctype_struct___1{f:0, g:0}}

如果你正在使用较旧的Go版本,可以尝试升级。如果仍然遇到问题,你也可以像我一样手动运行cgo命令,查看它生成了什么。

英文:

What version of Go are you using? Using Go 1.1.2, cgo seems to produce the expected output.

I ran go tool cgo main.go, and the generated _obj/_cgo_gotypes.go file contained the following definitions:

  1. type _Ctype_param_struct_t _Ctype_struct_param_struct_t
  2. type _Ctype_struct___0 struct {
  3. //line :1
  4. c _Ctype_int
  5. //line :1
  6. d _Ctype_int
  7. //line :1
  8. }
  9. type _Ctype_struct___1 struct {
  10. //line :1
  11. f _Ctype_int
  12. //line :1
  13. g _Ctype_int
  14. //line :1
  15. }
  16. type _Ctype_struct_param_struct_t struct {
  17. //line :1
  18. a _Ctype_int
  19. //line :1
  20. b _Ctype_int
  21. //line :1
  22. anon _Ctype_struct___0
  23. //line :1
  24. e _Ctype_int
  25. //line :1
  26. anon2 _Ctype_struct___1
  27. //line :1
  28. }

When I modified your program to correctly refr to c and d nested in the anon field and uncommented the other statements, the program compiled and ran with the final statement printing the struct as.

  1. main._Ctype_param_struct_t{a:0, b:0, anon:main._Ctype_struct___0{c:0, d:0}, e:0, anon2:main._Ctype_struct___1{f:0, g:0}}

If you are using an older version of Go, perhaps try upgrading. You could also try running cgo manually like I did to see what it is generating if you still run into problems.

答案2

得分: 0

我对cgo不太熟悉。但是你不能直接在Go代码中使用C类型,因为cgo会重新生成自己的类型。也许它是_C_param_struct_t。

请参考这个官方文档:http://golang.org/misc/cgo/gmp/gmp.go

英文:

I am not familiar with cgo. But you cannot directly use the C type in your go code as cgo as re-generated its own types. Maybe it's _C_param_struct_t.

Please refer to this official doc: http://golang.org/misc/cgo/gmp/gmp.go

huangapple
  • 本文由 发表于 2013年9月18日 15:41:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/18866462.html
匿名

发表评论

匿名网友

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

确定