go - CGO : Undefined symbols for architecture x86_64

标签 go linker cgo

我想从 C 函数空间调用 go func,但程序抛出构建错误。

例子.go

package main

/*
#include "test.c"
*/
import "C"
import "fmt"

func Example() {
    fmt.Println("this is go")
    fmt.Println(C.GoString(C.myprint(C.CString("go!!"))))
}

// export receiveC              (remove the extra space between // and export)
func receiveC(msg *C.char) {
    fmt.Println(C.GoString(msg))
}

func main() {
    Example()
}

测试.c

#include <stdio.h>

extern void receiveC(char *msg);

char* myprint(char *msg) {
    receiveC(msg);  // calling the exported go function
    return msg;     
    }

当我执行运行/构建命令(go buildgo run example.gogo build example.go)时程序,它抛出错误:

# github.com/subh007/goodl/cgo
Undefined symbols for architecture x86_64:
  "_receiveC", referenced from:
      _myprint in example.cgo2.o
      __cgo_6037ec60b2ba_Cfunc_myprint in example.cgo2.o
      _myprint in test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我正在关注 cgo slides编写程序。如有任何错误,请告诉我。

Edit1:我使用的是 OS-X 10.9 操作系统。

编辑2: 我在//export之间多了一个空格,//export之间应该没有空格。但是现在我在构建时遇到以下错误:

# github.com/subh007/goodl/cgo
duplicate symbol _myprint in:
    $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
    $WORK/github.com/subh007/goodl/cgo/_obj/example.cgo2.o
duplicate symbol _receiver_go in:
    $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
    $WORK/github.com/subh007/goodl/cgo/_obj/example.cgo2.o
duplicate symbol _myprint in:
    $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
    $WORK/github.com/subh007/goodl/cgo/_obj/test.o
duplicate symbol _receiver_go in:
    $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
    $WORK/github.com/subh007/goodl/cgo/_obj/test.o
ld: 4 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

最佳答案

生成重复符号是因为我将 test.c 直接包含到 go 文件中。所以这些符号被包含了两次。

我认为,编写这段代码的正确方法是(如果我错了请评论):

  1. 定义头文件(test.h):

     #ifndef TEST_H_
     #define TEST_H_
    
     char* myprint(char *msg);
    
     #endif
    
  2. 定义实现文件(test.c):

      #include <stdio.h>
      #include "test.h"
    
      extern void receiveC(char *msg);
    
      char* myprint(char *msg) {
          receiveC(msg);
          return msg;
       }
    
  3. .h 文件包含到 go 文件 (example.go) 中:

      package main
      /*
      #include "test.h"
      */
      import "C"
      import "fmt"
    
      func Example() {
           fmt.Println("this is go")
           fmt.Println(C.GoString(C.myprint(C.CString("go!!"))))
       }
    
       // make sure that there should be no space between the `//` and `export`
       //export receiveC
       func receiveC(msg *C.char) {
             fmt.Println(C.GoString(msg))
       }
    
       func main() {
            Example()
       }
    
  4. 构建程序:

      go build
    
  5. 运行生成的可执行文件(以cgo 名称生成的可执行文件,需要一些调查才能找到原因)。

      $./cgo
    

关于go - CGO : Undefined symbols for architecture x86_64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28593574/

相关文章:

go - 处理具有一个 "return"值的 goroutine 的惯用方式?

go - 我已经设置了我的 $GOPATH,但它不起作用

c++ - 对 `gnuplot_init()' 的 undefined reference

linker - 去-LDFLAGS : -w -hostobj gives error

使用CGo调用带有双指针输出参数的C函数

go - 如何分发具有 C 依赖项的 Go 模块

go - 在C函数中更改golang C.String变量的值

web - 如何从beego AppConfig获取值并在HTML模板中渲染?

c++ - 允许在 Cmake 中相互依赖

visual-c++ - VC++/DEFAULTLIB 问题