需要帮助固定 go/c 内存以进行 ffi 调用

问题描述 投票:0回答:1

我正在学习go和cgo和ffi,我有下面的头文件:

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct MyStruct3 {
  const char *const *data;
  int length;
} MyStruct3;

void my_struct_3(const struct MyStruct3 *c_data);

还有这个 go 文件

package main

/*
#cgo LDFLAGS: -L./release -lrust_ffi
#cgo CFLAGS: -I./target
#include <rust-ffi.h>
*/
import "C"
import (
    "fmt"
    "unsafe"
)

func main() {
    type MyStruct3 struct {
        data   **C.char
        length C.int
    }

    goStrings2 := []string{"Hello", "World", "from", "Go", "again"}

    pnr := new(runtime.Pinner)

    cStrings2 := make([]*C.char, len(goStrings2))
    for i, s := range goStrings2 {
        cString := C.CString(s)
        cStrings2[i] = cString
        // pnr.Pin(cString)
        defer C.free(unsafe.Pointer(cStrings2[i]))
    }

    cDataPtr := (**C.char)(unsafe.Pointer(&cStrings2[0]))
    // pnr.Pin(&goStrings2)
    pnr.Pin(&cDataPtr)
    // cLength := C.int(len(goStrings2))
    // pnr.Pin(&cLength)
    cStruct3 := MyStruct3{
        data:   cDataPtr,
        length: C.int(len(goStrings2)),
    }

    cStruct3prt := (*C.struct_MyStruct3)(unsafe.Pointer(&cStruct3))
    pnr.Pin(&cStruct3)
    C.my_struct_3(cStruct3prt)

    pnr.Unpin()

我收到以下错误

panic: runtime error: cgo argument has Go pointer to unpinned Go pointer

Go版本

$ go version
go version go1.21.5 linux/amd64

知道如何解决这个问题吗?

非常感谢你

go memory-management cgo
1个回答
0
投票

由于切片是由 Go 运行时分配的,因此您必须固定它:

func main() {
    goStrings2 := []string{"Hello", "World", "from", "Go", "again"}

    // Convert Go slice to a C array of C strings
    cStrings2 := make([]*C.char, len(goStrings2))
    for i, s := range goStrings2 {
        cStrings2[i] = C.CString(s)
        defer C.free(unsafe.Pointer(cStrings2[i]))
    }

    var pin runtime.Pinner
    defer pin.Unpin()

    cData := &cStrings2[0]
    pin.Pin(cData)
    C.my_struct_3(&C.MyStruct3{
        data:   cData,
        length: C.int(len(goStrings2)),
    })
}
© www.soinside.com 2019 - 2024. All rights reserved.