首页 > 解决方案 > 您如何将 Golang 的 cgo 与链接到 math.h 的 C 库一起使用?

问题描述

我目前正在尝试使用cgo. NOVAS 本质上是通过将源文件放置在您碰巧在其中工作的任何目录(不存在已编译的库文件)中来“安装”的,因此我相信我需要包含我将使用的 .c 文件(位于一个文件夹中)目录下的.go文件。

因此,我试图通过创建一个测试 .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)

我在 VirtualBox VM 实例中的 Ubuntu 18.04 (x64) 上运行。我在这里错过了特定的行吗?

我的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
   ...

标签: cgocompiler-errorscgomath.h

解决方案


您需要一个指令来告诉 go 链接器与 c 的数学库链接。标头math.h不包含数学函数的实现:只有它们的声明(第一个近似值)。

无论如何,您需要在 go 文件的注释中添加这一行:

#cgo LDFLAGS: -lm

-l意思是“与这个库的链接”,并且m是 C 的数学库的名称。


推荐阅读