C структура равна нулю при возврате в Go - PullRequest
0 голосов
/ 12 апреля 2020

Я пытаюсь создать структурную точку C и передать ее Go, но получаю нулевой указатель. У меня есть следующее в 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?

1 Ответ

4 голосов
/ 13 апреля 2020

Вы возвращаете указатель на структуру, выделенную в стеке, в C, что очень неправильно .

Указатель, возвращаемый из newTestStruct, по существу висящий , и попытка доступа к любым данным через него может привести к сбоям или, что еще хуже.

Убедитесь, что данные выделены на куча, если вы хотите вернуть указатель на него, что-то вроде:

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]

...