英文:
Golang (cgo) - Support for nested structs with cgo?
问题
我正在尝试使用cgo为x264库编写一个小的包装器,并遇到了嵌套结构的问题。该库使用了许多复杂的结构体,其中一些字段本身就是匿名结构体。
当尝试使用cgo访问这些结构体时,我遇到了编译错误,因为Go声称嵌套结构体不存在。
我已经将问题简化为下面粘贴的.h文件和.go文件。希望这足够清楚地显示问题。
有人知道这个问题的解决方案或变通方法吗?
谢谢。
struct.h
typedef struct param_struct_t {
int a;
int b;
struct {
int c;
int d;
} anon;
int e;
struct {
int f;
int g;
} anon2;
} param_struct_t;
main.go
package main
/*
#include "struct.h"
*/
import "C"
import (
"fmt"
)
func main() {
var param C.param_struct_t
fmt.Println(param.a) // 正常工作,应该可以工作
fmt.Println(param.b) // 正常工作,应该可以工作
fmt.Println(param.c) // 正常工作,但不应该可以工作
fmt.Println(param.d) // 正常工作,但不应该可以工作
// fmt.Println(param.e) // 产生类型错误:./main.go:17: param.e undefined (type C.param_struct_t has no field or method e)
// fmt.Println(param.anon) // 产生类型错误:./main.go:18: param.anon undefined (type C.param_struct_t has no field or method anon)
// 下面的代码显示第一个参数和第一个匿名结构体的参数被正确读取,但后续的内容被读取为似乎是原始字节。
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}}
}
英文:
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
typedef struct param_struct_t {
int a;
int b;
struct {
int c;
int d;
} anon;
int e;
struct {
int f;
int g;
} anon2;
} param_struct_t;
main.go
package main
/*
#include "struct.h"
*/
import "C"
import (
"fmt"
)
func main() {
var param C.param_struct_t
fmt.Println(param.a) // Works and should work
fmt.Println(param.b) // Works and should work
fmt.Println(param.c) // Works fine but shouldn't work
fmt.Println(param.d) // Works fine but shouldn't work
// fmt.Println(param.e) // Produces type error: ./main.go:17: param.e undefined (type C.param_struct_t has no field or method e)
// fmt.Println(param.anon) // Produces type error: ./main.go:18: param.anon undefined (type C.param_struct_t has no field or method anon)
// The following shows that the first parameters and the parameters from the
// first anonymous struct gets read properly, but the subsequent things are
// read as seemingly raw bytes.
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}}
}
答案1
得分: 2
你正在使用哪个版本的Go?使用Go 1.1.2,cgo似乎产生了预期的输出。
我运行了go tool cgo main.go
命令,生成的_obj/_cgo_gotypes.go
文件包含了以下定义:
type _Ctype_param_struct_t _Ctype_struct_param_struct_t
type _Ctype_struct___0 struct {
//line :1
c _Ctype_int
//line :1
d _Ctype_int
//line :1
}
type _Ctype_struct___1 struct {
//line :1
f _Ctype_int
//line :1
g _Ctype_int
//line :1
}
type _Ctype_struct_param_struct_t struct {
//line :1
a _Ctype_int
//line :1
b _Ctype_int
//line :1
anon _Ctype_struct___0
//line :1
e _Ctype_int
//line :1
anon2 _Ctype_struct___1
//line :1
}
当我修改了你的程序,正确地引用了anon
字段中嵌套的c
和d
,并取消了其他语句的注释后,程序编译并运行,最后一条语句打印了结构体:
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:
type _Ctype_param_struct_t _Ctype_struct_param_struct_t
type _Ctype_struct___0 struct {
//line :1
c _Ctype_int
//line :1
d _Ctype_int
//line :1
}
type _Ctype_struct___1 struct {
//line :1
f _Ctype_int
//line :1
g _Ctype_int
//line :1
}
type _Ctype_struct_param_struct_t struct {
//line :1
a _Ctype_int
//line :1
b _Ctype_int
//line :1
anon _Ctype_struct___0
//line :1
e _Ctype_int
//line :1
anon2 _Ctype_struct___1
//line :1
}
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.
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论