当 return 在 Go 中时,C 结构为 nil

C struct is nil when return in Go

我正在尝试创建一个 C 结构点并将其传递给 Go,但我一直得到一个 nil 指针。我在 C 中有以下内容并从 Go 调用。

test.h

#include <stdio.h>

typedef struct TestStruct {
    int test_int;
} TestStruct;

TestStruct* newTestStruct();

test.c

TestStruct* newTestStruct() {
    printf("[C] Creating TestStruct...\n");
    TestStruct test = {0};

    test.test_int = 10;

    TestStruct* testPtr = &test;

    if (testPtr == NULL) {
        printf("[C] TestStruct is NULL.\n");
    }

    fflush(stdout);
    return testPtr;
}

test.go

package teststruct

import "log"

// #include "test.h"
import "C"

type TestStruct C.struct_TestStruct

func NewTestStruct() *TestStruct {
    t := C.newTestStruct()

    if t == nil {
        log.Errorf("[Go] TestStruct is nil.")
    }

    return (*TestStruct)(t)
}

它打印出以下内容:

[C] Creating TestStruct...
[Go] TestStruct is nil.

为什么 Go 端是 nil?

您return在 C 中使用指向堆栈分配结构的指针,这是非常错误的

newTestStruct 中 return 得到的指针本质上是 悬空 并且尝试通过它访问任何数据可能会导致崩溃或更糟。

如果你想 return 指向它的指针,请确保在堆上分配数据,例如:

TestStruct* newTestStruct() {
    printf("[C] Creating TestStruct...\n");
    TestStruct* testPtr = (TestStruct*)malloc(sizeof(TestStruct));
    testPtr->test_int = 10;

    if (testPtr == NULL) {
        printf("[C] TestStruct is NULL.\n");
    }

    fflush(stdout);
    return testPtr;
}

顺便说一句,在任何半现代 C 编译器上,您都会收到针对 C 代码的警告,例如 warning: function returns address of local variable [-Wreturn-local-addr]