Golang cgo * Разница в размерах C.int - PullRequest
0 голосов
/ 20 марта 2019

Я исследую CGO и столкнулся с причудой, когда размер C.int во время выполнения go составляет 8 байтов, а C int составляет 4 байта.Я понимаю, что Go-целочисленные значения могут быть 64-битными или 32-битными в зависимости от архитектуры, а C-целые всегда 32-битные.Существует ли стандартный способ указания перехода на использование 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.с

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]);
}

1 Ответ

0 голосов
/ 20 марта 2019

Я понял это. Глупая ошибка. Я увеличиваю на размер указателя - 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)
}
...