如何在不同操作系统上一致地将C的uint64_t转换为Cgo?

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

How to convert C uint64_t to Cgo consistently across OS?

问题

我正在使用一些C库来处理Go语言,使用cgo来处理转换。

我有一个C头文件,看起来像这样:

#include <stdlib.h>

typedef struct {
   uint64_t k;
} params;

这个结构体在Go语言中被使用,代码如下:

package test

/*
#cgo CFLAGS: -g -Wall
#cgo LDFLAGS: -L. -lmylib -lm -ldl
#include "mylib.h"
*/
import "C"
func NewParams(k uint64) Params {
  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上失败。

如何确保相同的代码在两个平台上都能正常工作?

英文:

I am using some C library form Go, using cgo to handle the conversion.

I have a C header file that looks like:

#include &lt;stdlib.h&gt;

typedef struct {
   k uint64_t;
} params;

This structure is used from Go with code like:

package test

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

The code compiles fine on OS X with Apple clang version 12.0.0, but fails on Linux with clang version 7.1.0, yielding the following error:

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

If I change the call to C.ulonglong to C.ulong, it works fine on linux but then fails on OS X.

How can I ensure the same code works on both platform?

答案1

得分: 2

使用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

英文:

Using go build -work I was able to confirm the issue stems from differences in mapping:

  • On the linux side, a C unit64_t gets mapped to a C.ulong
  • On the Mac side, it gets mapped to C.ulonglong

Note that both C.ulong and C.ulonglong gets mapped to a go uint64 but using the Go type directly and removing the C.xxx(k) conversion fails.

Solution is to use C.uint64_t(k) which makes it explicit the size of the type we are talking about. This is just fine because the C type is uin64_t anyways.

huangapple
  • 本文由 发表于 2021年12月6日 18:01:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/70243683.html
匿名

发表评论

匿名网友

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

确定