You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向C函数传递void指针?解决cgo的Go指针嵌套报错

解决cgo传递指针时的"cgo argument has Go pointer to Go pointer"错误

这个错误的本质是cgo的安全限制:你传递了一个指向Go指针的Go指针给C函数。Go的垃圾回收器会自主管理Go内存的分配与释放,甚至可能移动内存位置,但C代码无法感知这些操作,这种指针传递方式会引发内存安全风险,因此被cgo禁止。

解决方案:用C内存中转指针

核心思路是用C的内存分配函数存储需要传递的指针,让C函数操作C内存中的指针值,而非直接操作Go指针的指针。示例代码如下:

package main

//
// void test(void **data) {
//     // 示例操作:修改指针指向
//     *data = NULL;
// }
import "C"

import (
    "unsafe"
)

func main() {
    var data *C.void
    // 分配一块C内存,用来存储指针值
    cMem := C.malloc(C.size_t(unsafe.Sizeof(data)))
    defer C.free(cMem) // 确保函数退出时释放C内存,避免泄漏

    // 将Go指针的值拷贝到C内存中
    *(*unsafe.Pointer)(cMem) = unsafe.Pointer(data)

    // 传递指向C内存的指针给C函数
    C.test((**C.void)(cMem))

    // 若需要,可将C函数修改后的指针值拷贝回Go变量
    data = (*C.void)(*(*unsafe.Pointer)(cMem))
}

额外说明

  • 如果你的C函数是要分配内存并通过输出参数返回,更简洁的方式是让C函数直接返回指针,Go代码接收后用unsafe.Pointer转换使用,避免复杂的指针嵌套传递。
  • 永远不要让C代码长期持有Go指针(包括指向Go内存的指针),Go GC无法追踪C代码持有的引用,可能导致内存被提前回收。

内容的提问来源于stack exchange,提问作者Marc Fuller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:15:05