如何跨操作系统一致地将 C uint64_t 转换为 Cgo?

Posted

技术标签:

【中文标题】如何跨操作系统一致地将 C uint64_t 转换为 Cgo?【英文标题】:How to convert C uint64_t to Cgo consistently across OS? 【发布时间】: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 上会失败。

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

【问题讨论】:

【参考方案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 反正。

【讨论】:

以上是关于如何跨操作系统一致地将 C uint64_t 转换为 Cgo?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ARM 上的 uint64_t 和 poly64_t 之间进行转换?

C语言之如何输出uint32_t和uint64_t和16进制

防止将 uint64_t 转换为 uint16_t

从 uint8_t* 到 uint32_t 的无效转换 - 从 32 位架构迁移到 64 位架构时?

将 __m256i 寄存器转换为 uint64_t 位掩码,以便每个字节值处的值是输出中的设置位

无法将 eosio::name 转换为 uint64_t