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

如何在CGO中向Go函数传递C结构体并转换为Go结构体?

CGO中C函数向Go函数传递结构体的解决方案

核心问题修正

你的代码存在两个关键问题:一是C的struct Person定义在函数内部,Go无法识别该类型;二是Go回调函数用interface{}作为参数,没法直接解析C结构体。下面是具体解决步骤:

1. 把C结构体移到全局区域

C里的结构体必须定义在全局作用域,这样CGO才能为Go生成对应的类型:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// 全局定义结构体,让Go能识别
struct Person{
    int age;
    char name[100];
};

__attribute__((weak))
void testCFunc()
{
    struct Person pers;
    pers.age = 21;
    strcpy(pers.name, "John Doe");
    // 推荐传指针,避免大结构体拷贝
    goCallbackHandler(&pers);
}

2. 定义匹配的Go回调函数参数

Go回调函数要直接接收*C.struct_Person类型(如果传值就用C.struct_Person,指针更高效),然后把C结构体字段逐个转换为Go结构体:

//export goCallbackHandler
func goCallbackHandler(cPers *C.struct_Person) {
    // 转换为Go结构体
    goPers := Person{
        age: int(cPers.age),
        // 把C的char数组转成Go字符串,自动处理'\0'结束符
        name: C.GoString(&cPers.name[0]),
    }

    fmt.Println("转换后的Go结构体:")
    fmt.Printf("年龄:%d,姓名:%s\n", goPers.age, goPers.name)
}

3. 完整可运行代码

package main

import (
    "fmt"
)

/*
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct Person{
    int age;
    char name[100];
};

__attribute__((weak))
void testCFunc()
{
    struct Person pers;
    pers.age = 21;
    strcpy(pers.name, "John Doe");
    goCallbackHandler(&pers);
}
*/
import "C"

type Person struct {
    age  int
    name string
}

//export goCallbackHandler
func goCallbackHandler(cPers *C.struct_Person) {
    goPers := Person{
        age:  int(cPers.age),
        name: C.GoString(&cPers.name[0]),
    }

    fmt.Println("接收并转换后的Go结构体内容:")
    fmt.Printf("年龄:%d,姓名:%s\n", goPers.age, goPers.name)
}

func main() {
    // 调用C函数触发回调
    C.testCFunc()
}

复杂结构体扩展提示

如果后续使用嵌套结构体、带指针成员的复杂结构体,处理逻辑一致:

  • 先在C全局区域定义完整的结构体(包括嵌套的子结构体);
  • Go中用C.struct_XXX或*C.struct_XXX接收;
  • 指针类型字段需要用unsafe.Pointer辅助转换,比如C的char*可以直接用C.GoString,如果是自定义结构体指针,转成*C.struct_SubXXX后再处理字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:51:26