【问题标题】:Using empty struct properly with CGO在 CGO 中正确使用空结构
【发布时间】:2014-04-15 11:11:26
【问题描述】:

使用gssapi.h

struct gss_name_struct;
typedef struct gss_name_struct * gss_name_t;

我正在尝试弄清楚如何正确初始化包含此变量的变量

var output_name C.gss_name_t = &C.struct_gss_name_struct{}

但是像gss_import_name 这样的函数就像我将空指针传递给它们一样。在 CGO 中正确初始化和使用这些空结构的正确方法是什么?

【问题讨论】:

    标签: go cgo


    【解决方案1】:

    Go 的严格类型使得 typedef 难以使用。让你的 Go 看起来清晰的最好方法是用 C 编写一个小的包装函数来完全按照你想要的方式构建结构。不过,在这种情况下,go 对空的 C 结构使用零长度字节数组,您可以在下面验证。可以直接在go中声明,必要时进行转换。

    由于 C 对类型并不严格,使用类型推断通常是分配 Go 期望的类型的最简单方法。还有一个技巧是使用 cgo 工具来显示您需要的类型声明。使用 go tool cgo -godefs filename.go 将输出您的类型的 cgo 定义。正如您所看到的,go 等效类型可能会有点混乱。

    // statement in the original .go file
    //var output_name C.gss_name_t = &C.struct_gss_name_struct{}
    
    // output from cgo -godefs
    // var output_name *[0]byte = &[0]byte{}
    
    // or more succinctly
    output_name := &[0]byte{}
    
    // output_name can be converted directly to a C.gss_name_t
    fmt.Printf("%+v\n", output_name)
    fmt.Printf("%+v\n", C.gss_name_t(output_name))
    

    【讨论】:

    • 这确实有效。不过需要注意的是,打印 [0] 字节的效率不是很高(实际上并没有打印任何东西)。没问题,gssapi 具有用于提取字符串表示的 C 函数。我只是想我会提一下,以免其他人感到困惑。
    猜你喜欢
    • 2013-09-22
    • 2019-06-03
    • 2015-03-21
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 2023-03-29
    • 2022-06-23
    • 1970-01-01
    相关资源
    最近更新 更多