【问题标题】:Golang cgo *C.int size differencesGolang cgo *C.int 大小差异
【发布时间】:2019-08-11 11:17:42
【问题描述】:

我正在探索 CGO,我遇到了一个怪癖,即 go 运行时中 C.int 的大小为 8 字节,但 C int 为 4 字节。我知道 Go 整数可以是 64 位或 32 位,具体取决于架构,而 C 整数始终是 32 位。是 有一种标准方法可以告诉 go 使用 4 个字节的 C.int 类型吗?我无法找到与此相关的文档。

因此,代码无法按预期运行。它基本上将低端添加到第一个 int 的高端。它从不引用传递的第二个 int。

提前致谢。

实际输出:

0xc00001a0b0
0xc00001a0b8
0xc00001a0b0
0xc00001a0b4
199
0
199

main.go

package main

/*
int addNums(int *nums);
*/
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    var nums [2]C.int
    numsPtr := (*C.int)(unsafe.Pointer(&nums))
    fmt.Println(numsPtr)
    *numsPtr = 199
    numsPtr = (*C.int)(unsafe.Pointer(uintptr(unsafe.Pointer(numsPtr)) + unsafe.Sizeof(numsPtr)))
    fmt.Println(numsPtr)
    *numsPtr = 3
    res, err := C.addNums((*C.int)(unsafe.Pointer(&nums[0])))
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(res)
}

lib.c

long addNums(int *nums)
{
  printf("%p\n", &nums[0]);
  printf("%p\n", &nums[1]);
  printf("%d\n", nums[0]);
  printf("%d\n", nums[1]);
  return (nums[0] + nums[1]);
}

【问题讨论】:

  • unsafe.Pointer(uintptr(unsafe.Pointer(&nums))) 的意图是什么?额外的unintptrunsafe.Pointer 不应该做任何事情。
  • 感谢您指出这一点。这可能只是匆忙的复制粘贴。它可以被删除。

标签: c go types cgo


【解决方案1】:

我想通了。愚蠢的错误。我增加了指针的大小——64 位地址——而不是 int 的大小。修改后的 go 文件:

package main

/*
int addNums(int *nums);
*/
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    var nums [2]int32
    fmt.Println(unsafe.Sizeof(nums))
    numsPtr := (*C.int)(unsafe.Pointer(uintptr(unsafe.Pointer(&nums))))
    fmt.Println(numsPtr)
    *numsPtr = 199
    numsPtr = (*C.int)(unsafe.Pointer(uintptr(unsafe.Pointer(numsPtr)) + unsafe.Sizeof(*numsPtr)))
    fmt.Println(numsPtr)
    *numsPtr = 3
    res, err := C.addNums((*C.int)(unsafe.Pointer(&nums)))
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(res)
}

【讨论】:

    猜你喜欢
    • 2019-07-19
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多