【问题标题】:multiple definition when using cgo使用cgo时的多重定义
【发布时间】:2020-02-24 15:51:56
【问题描述】:
package main

/*
int add(int a, int b) {
    return a + b;
}
*/
import "C"
import "fmt"

func main() {}

func Test1() {
    fmt.Println(C.add(1, 3))
}

//export Test2
func Test2() {

}

编译程序:

dingrui@dingrui-PC:~/Projects/gotest/array$ go build -o libtest.so -buildmode=c-shared main.go 
# command-line-arguments
/tmp/go-build043762604/b001/_x002.o: In function `add':
./main.go:5: multiple definition of `add'
/tmp/go-build043762604/b001/_x001.o:/tmp/go-build/main.go:5: first defined here
collect2: error: ld returned 1 exit status

如果我删除“//export Test2”行,它编译成功。

【问题讨论】:

    标签: go cgo


    【解决方案1】:

    此行为已记录在 here

    在文件中使用 //export 对前导有一个限制:因为它被复制到两个不同的 C 输出文件中,所以它不能包含任何定义,只能包含声明。如果一个文件同时包含定义和声明,那么这两个输出文件将产生重复的符号并且链接器将失败。为避免这种情况,必须将定义放在其他文件或 C 源文件的序言中。

    【讨论】:

      【解决方案2】:

      如果您不介意重复代码,这是一个丑陋的解决方法:

      package main
      
      /*
      __attribute__((weak))
      int add(int a, int b) {
          return a + b;
      }
      */
      import "C"
      import "fmt"
      
      func main() {}
      
      func Test1() {
          fmt.Println(C.add(1, 3))
      }
      
      //export Test2
      func Test2() {
      
      }
      

      IIUC __attribute__((weak)) 告诉链接器忽略重复的定义。

      【讨论】:

        猜你喜欢
        • 2020-04-17
        • 2020-11-26
        • 2021-01-05
        • 2021-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-14
        • 2015-06-08
        相关资源
        最近更新 更多