cgo:x86_64 架构的未定义符号。

huangapple go评论113阅读模式
英文:

cgo : Undefined symbols for architecture x86_64

问题

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

example.go

  1. package main
  2. /*
  3. #include "test.c"
  4. */
  5. import "C"
  6. import "fmt"
  7. func Example() {
  8. fmt.Println("this is go")
  9. fmt.Println(C.GoString(C.myprint(C.CString("go!!"))))
  10. }
  11. // export receiveC (移除//和export之间的额外空格)
  12. func receiveC(msg *C.char) {
  13. fmt.Println(C.GoString(msg))
  14. }
  15. func main() {
  16. Example()
  17. }

test.c

  1. #include <stdio.h>
  2. extern void receiveC(char *msg);
  3. char* myprint(char *msg) {
  4. receiveC(msg); // 调用导出的go函数
  5. return msg;
  6. }

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

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

我正在按照cgo幻灯片编写程序。如果有任何错误,请告诉我。

编辑1:我正在使用OS-X 10.9操作系统。

编辑2:
我在// export之间有一个额外的空格,//export之间不应该有空格。但是现在在构建时我得到以下错误:

  1. # github.com/subh007/goodl/cgo
  2. duplicate symbol _myprint in:
  3. $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
  4. $WORK/github.com/subh007/goodl/cgo/_obj/example.cgo2.o
  5. duplicate symbol _receiver_go in:
  6. $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
  7. $WORK/github.com/subh007/goodl/cgo/_obj/example.cgo2.o
  8. duplicate symbol _myprint in:
  9. $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
  10. $WORK/github.com/subh007/goodl/cgo/_obj/test.o
  11. duplicate symbol _receiver_go in:
  12. $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
  13. $WORK/github.com/subh007/goodl/cgo/_obj/test.o
  14. ld: 4 duplicate symbols for architecture x86_64
  15. clang: error: linker command failed with exit code 1 (use -v to see invocation)
英文:

I would like to call the go func from the C function space, but the program throws the build error.

example.go

  1. package main
  2. /*
  3. #include &quot;test.c&quot;
  4. */
  5. import &quot;C&quot;
  6. import &quot;fmt&quot;
  7. func Example() {
  8. fmt.Println(&quot;this is go&quot;)
  9. fmt.Println(C.GoString(C.myprint(C.CString(&quot;go!!&quot;))))
  10. }
  11. // export receiveC (remove the extra space between // and export)
  12. func receiveC(msg *C.char) {
  13. fmt.Println(C.GoString(msg))
  14. }
  15. func main() {
  16. Example()
  17. }

test.c

  1. #include &lt;stdio.h&gt;
  2. extern void receiveC(char *msg);
  3. char* myprint(char *msg) {
  4. receiveC(msg); // calling the exported go function
  5. return msg;
  6. }

When I execute the command to run/build (go build or go run example.go or go build example.go) the program, it throws the error:

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

I am following the cgo slides to writing the program. Please let me know for any mistakes here.

Edit1: I am using OS-X 10.9 OS.

Edit2:
I have one extra space between // export, there should be no space between // and export. But now I am getting the following error while building :

  1. # github.com/subh007/goodl/cgo
  2. duplicate symbol _myprint in:
  3. $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
  4. $WORK/github.com/subh007/goodl/cgo/_obj/example.cgo2.o
  5. duplicate symbol _receiver_go in:
  6. $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
  7. $WORK/github.com/subh007/goodl/cgo/_obj/example.cgo2.o
  8. duplicate symbol _myprint in:
  9. $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
  10. $WORK/github.com/subh007/goodl/cgo/_obj/test.o
  11. duplicate symbol _receiver_go in:
  12. $WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
  13. $WORK/github.com/subh007/goodl/cgo/_obj/test.o
  14. ld: 4 duplicate symbols for architecture x86_64
  15. clang: error: linker command failed with exit code 1 (use -v to see invocation)

答案1

得分: 4

重复的符号是因为我直接将test.c包含在go文件中。所以符号被包含了两次。

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

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

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

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

    1. package main
    2. /*
    3. #include "test.h"
    4. */
    5. import "C"
    6. import "fmt"
    7. func Example() {
    8. fmt.Println("this is go")
    9. fmt.Println(C.GoString(C.myprint(C.CString("go!!"))))
    10. }
    11. // 确保`//`和`export`之间没有空格
    12. //export receiveC
    13. func receiveC(msg *C.char) {
    14. fmt.Println(C.GoString(msg))
    15. }
    16. func main() {
    17. Example()
    18. }
  4. 构建程序:

    1. go build
  5. 运行生成的可执行文件(可执行文件的名称是通过cgo生成的,需要进行一些调查找出原因)。

    1. $./cgo
英文:

Duplicate symbols are generated because I have included the test.c directly to the go file. So the symbols are included twice.

I think, the correct way of writing this code is (please comment if I am wrong) to:

  1. Define the header file (test.h):

    1. #ifndef TEST_H_
    2. #define TEST_H_
    3. char* myprint(char *msg);
    4. #endif
  2. Define the implementation file (test.c):

    1. #include &lt;stdio.h&gt;
    2. #include &quot;test.h&quot;
    3. extern void receiveC(char *msg);
    4. char* myprint(char *msg) {
    5. receiveC(msg);
    6. return msg;
    7. }
  3. Include the .h file to the go file (example.go) :

    1. package main
    2. /*
    3. #include &quot;test.h&quot;
    4. */
    5. import &quot;C&quot;
    6. import &quot;fmt&quot;
    7. func Example() {
    8. fmt.Println(&quot;this is go&quot;)
    9. fmt.Println(C.GoString(C.myprint(C.CString(&quot;go!!&quot;))))
    10. }
    11. // make sure that there should be no space between the `//` and `export`
    12. //export receiveC
    13. func receiveC(msg *C.char) {
    14. fmt.Println(C.GoString(msg))
    15. }
    16. func main() {
    17. Example()
    18. }
  4. Build the program :

    1. go build
  5. run the generated executable (the executable file generate with the cgo name, need some investigation to find the reason).

    1. $./cgo

huangapple
  • 本文由 发表于 2015年2月19日 04:45:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/28593574.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定