Вызов функции c, порядок импорта fmt, импорт C вызывает ошибку сборки, почему?

У меня есть следующий простой тестовый код: call_c.go

package main

/*
int getData(int *p, int n )
{
     int i; 
     for(i=0;i<n;i++) {
        p[i]=i;
    } 
    return n;
}
*/
import "C"
import "fmt"

func main() {
    var a [5]int32
    i := C.getData((*C.int)(&a[0]), 5)
    fmt.Println(i, a)
}

Я использую "go build call_c.go" для сборки программы, и она отлично строится.

Но я обнаружил, что если я просто изменю порядок «import fmt», «import C» или добавлю новую строку между кодом блока C /* */ и первым оператором импорта, команда «go build call_c.go» вернет ошибка:

go build call_c.go
37: error: 'getData' undeclared (first use in this function)

Вопросы к знатокам сусликов:

Почему порядок импорта важен в go?

Почему я не могу добавить пробел между блоком C и первым оператором импорта?

Если я снова увижу такую ​​ошибку, как лучше всего ее отладить?


person tony-p-lee    schedule 16.10.2014    source источник


Ответы (2)


Порядок импорта в общем случае не важен. Но import "C" очень особенный при использовании cgo.

Из документов:

Если импорту "C" непосредственно предшествует комментарий, этот комментарий, называемый преамбулой, используется в качестве заголовка при компиляции частей пакета C. Например:

// #include <stdio.h>
// #include <errno.h>
import "C"

Итак, если у вас есть новая строка между вашим комментарием, содержащим код C, и import "C" , то комментарий является просто еще одним комментарием и не обрабатывается cgo.

Точно так же, если вы измените порядок импорта:

/*
int getData(int *p, int n )
{
     int i; 
     for(i=0;i<n;i++) {
        p[i]=i;
    } 
    return n;
}
*/
import "fmt"
import "C"

Код в комментарии является просто еще одним комментарием и не обрабатывается cgo, поскольку сразу за ним не следует импорт "C". (точнее, import "C" не предшествует комментарий)

person nos    schedule 16.10.2014
comment
Хороший ответ! Это первый раз, когда я вхожу в язык, где новая строка может вызвать ошибку компиляции. Теперь я знаю, почему. Спасибо еще раз. - person tony-p-lee; 16.10.2014

Это важно только потому, что этот инструмент определен для работы -- golang.org/cmd/cgo/

Большая часть цепочки инструментов Go основана на соглашениях, и вам необходимо следовать соответствующим соглашениям, чтобы они работали правильно.

person JimB    schedule 16.10.2014