【问题标题】:How to convert C uint64_t to Cgo consistently across OS?如何跨操作系统一致地将 C uint64_t 转换为 Cgo?
【发布时间】:2022-01-11 13:19:51
【问题描述】:

我正在使用一些 C 库形式的 Go,使用 cgo 来处理转换。

我有一个 C 头文件,如下所示:

#include <stdlib.h>

typedef struct {
   k uint64_t;
} params;

这个结构在 Go 中使用,代码如下:

package test

/*
#cgo CFLAGS: -g -Wall
#cgo LDFLAGS: -L. -lmylib -lm -ldl
#include "mylib.h"
*/
import "C"
func NewParams(k uint64) Paramets {
  return Params{
    k:     C.ulonglong(k),
  }
}

代码在使用 Apple clang 版本 12.0.0 的 OS X 上编译良好,但在使用 clang 版本 7.1.0 的 Linux 上编译失败,产生以下错误:

cannot use _Ctype_ulonglong(k) (type _Ctype_ulonglong) as type _Ctype_ulong in field value

如果我将调用 C.ulonglong 更改为 C.ulong,它在 linux 上可以正常工作,但在 OS X 上会失败。

我如何确保相同的代码在两个平台上都可以运行?

【问题讨论】:

    标签: c go cgo


    【解决方案1】:

    使用go build -work 我能够确认问题源于映射差异:

    • 在 linux 端,C unit64_t 被映射到 C.ulong
    • 在 Mac 端,它被映射到 C.ulonglong

    请注意,C.ulongC.ulonglong 都映射到 go uint64,但直接使用 Go 类型并删除 C.xxx(k) 转换失败。

    解决方案是使用C.uint64_t(k),它明确了我们正在讨论的类型的大小。这很好,因为 C 类型 uin64_t 反正。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多