Как вы используете cgo Golang с библиотеками C, которые ссылаются на math.h?

В настоящее время я пытаюсь создать оболочку Golang для Пакет NOVAS C (пакет астрометрии/астрономии) с помощью cgo. NOVAS, по сути, «устанавливается», помещая исходные файлы в любой каталог, в котором вы работаете (файлы скомпилированных библиотек отсутствуют), поэтому я считаю, что мне нужно включить файлы .c, которые я буду использовать (которые находятся в папке один каталог вниз от файла .go.

Таким образом, я пытаюсь проверить это, создав тестовую программу .go, которая сама вызывает функцию в novas.c. Однако программа не скомпилируется, по-видимому, из-за множества неопределенных ссылок на функции, присутствующие в math.h; это странно, потому что math.h включен как в мой файл .go, так и в файлы C, которые я собираюсь использовать.

go run novasTest.go 
# command-line-arguments
/tmp/go-build681583835/b001/_x002.o: In function `equ2gal':
./Cdist/novas.c:1995: undefined reference to `sincos'
./Cdist/novas.c:1996: undefined reference to `sincos'
./Cdist/novas.c:2033: undefined reference to `atan2'
./Cdist/novas.c:2025: undefined reference to `atan2'
./Cdist/novas.c:2022: undefined reference to `sqrt'
/tmp/go-build681583835/b001/_x002.o: In function `era':
./Cdist/novas.c:3242: undefined reference to `fmod'
./Cdist/novas.c:3242: undefined reference to `fmod'
...(etcetera)

Я использую Ubuntu 18.04 (x64) в экземпляре виртуальной машины VirtualBox. Я пропустил определенную строку здесь?

Моя программа go выглядит так:

package main

/*
#include "Cdist/novas.h"
#include "Cdist/novas.c"
#include "Cdist/novascon.c"
#include "Cdist/nutation.c"
#include <math.h>
*/
import "C"
import "log"  

func main() {
    log.Println("Test of NOVAS function")
    var JulianHigh C.double
    var JulianLow C.double
    ...
    var Z C.double

    // Test values
    JulianHigh = 2458953.5 
    JulianLow = 1.0
    ...
    Z = -1.437110810486059E+03

    vCel := make([]C.double,0) //Create the array to pass to the function.
    vCel = append(vCel, X)
    ...
    vTerFirst := &(vTer[0])

    C.cel2ter(JulianHigh,JulianLow,DeltaT,Method,Accuracy,Option,PolarX,PolarY,vCelFirst,vTerFirst)

    log.Println("C function completed processing.")
}

Программа C слишком велика для включения, поэтому вместо этого я покажу соответствующие части файлов novas.h и novas.c.

Файл C:

/*
  ...
  novas.c: Main library
  ...
*/

#ifndef _NOVAS_
   #include "novas.h"
#endif

#include <math.h>
... //(other functions follow until the necessary one)
/********cel2ter */

short int cel2ter (double jd_ut_high, double jd_ut_low, double delta_t,
                   short int method, short int accuracy, short int option,
                   double xp, double yp, double *vec1,

                   double *vec2)
/*
------------------------------------------------------------------------

   PURPOSE:
      This function...

Обратите внимание, что сама функция зависит от функций, которые вызывают вызовы из других файлов, которые я включил.

Файл .h:

/*
  ...
  novas.h: Header file for novas.c
  ...
*/

#ifndef _NOVAS_
   #define _NOVAS_

   #ifndef __STDIO__
      #include <stdio.h>
   #endif

   #ifndef __MATH__
      #include <math.h>
   #endif

   #ifndef __STRING__
      #include <string.h>
   #endif
   ...

person jos    schedule 17.04.2020    source источник


Ответы (1)


Вам нужна директива, чтобы сообщить компоновщику go, что нужно линковаться с математической библиотекой c. Заголовок math.h не содержит реализации математических функций: только их объявления (в первом приближении).

В любом случае вам нужно добавить эту строку в комментарий в вашем файле go:

#cgo LDFLAGS: -lm

-l означает «связать с этой библиотекой», а m — это имя математической библиотеки C.

person Paul Hankin    schedule 17.04.2020
comment
Извините, а где это находится в коде go? В разделе верхнего включения? - person jos; 17.04.2020
comment
Перед вашим включает. Думаю, я получил правильный вызов с golang.org/cmd/cgo. - person Paul Hankin; 17.04.2020
comment
Спасибо - это было исправление для этой конкретной ошибки. У меня все еще есть другие ошибки, но они не связаны с этим (необходимо импортировать больше файлов и уточнить ввод функции) - person jos; 17.04.2020