duande9301 2019-03-20 16:56
浏览 238

Golang cgo * C.int大小差异

I am exploring CGO and I have run into a quirk where the size of C.int in the go runtime is 8 bytes but the C int is 4 bytes. I understand that Go ints can be 64 bits or 32 bits depending on architecture, and that C ints are always 32 bits. Is there a standard way for telling go to use 4 bytes for C.int types? I have not been able to find documentation that deals with this.

Because of this the code does not function as anticipated. It basically adds the low side to the high side of the first int. It never references the second int passed.

Thanks in advance.

Actual output:

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
", &nums[0]);
  printf("%p
", &nums[1]);
  printf("%d
", nums[0]);
  printf("%d
", nums[1]);
  return (nums[0] + nums[1]);
}
  • 写回答

1条回答 默认 最新

  • 普通网友 2019-03-20 17:07
    关注

    I figured it out. Silly mistake. I am incrementing by the size of the pointer - 64bit address - rather than the size of the int. Revised go file:

    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)
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥20 @microsoft/fetch-event-source 流式响应问题
  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False