英文:
cgo : Undefined symbols for architecture x86_64
问题
我想从C函数空间调用go函数,但程序抛出了构建错误。
example.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 (移除//和export之间的额外空格)
func receiveC(msg *C.char) {
fmt.Println(C.GoString(msg))
}
func main() {
Example()
}
test.c
#include <stdio.h>
extern void receiveC(char *msg);
char* myprint(char *msg) {
receiveC(msg); // 调用导出的go函数
return msg;
}
当我执行运行/构建的命令(go build
或go run example.go
或go 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幻灯片编写程序。如果有任何错误,请告诉我。
编辑1:我正在使用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)
英文:
I would like to call the go func from the C function space, but the program throws the build error.
example.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()
}
test.c
#include <stdio.h>
extern void receiveC(char *msg);
char* myprint(char *msg) {
receiveC(msg); // calling the exported go function
return msg;
}
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:
# 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)
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 :
# 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)
答案1
得分: 4
重复的符号是因为我直接将test.c
包含在go文件中。所以符号被包含了两次。
我认为,编写这段代码的正确方式是(如果我错了,请评论):
-
定义头文件(test.h):
#ifndef TEST_H_ #define TEST_H_ char* myprint(char *msg); #endif
-
定义实现文件(test.c):
#include <stdio.h> #include "test.h" extern void receiveC(char *msg); char* myprint(char *msg) { receiveC(msg); return msg; }
-
将
.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!!")))) } // 确保`//`和`export`之间没有空格 //export receiveC func receiveC(msg *C.char) { fmt.Println(C.GoString(msg)) } func main() { Example() }
-
构建程序:
go build
-
运行生成的可执行文件(可执行文件的名称是通过
cgo
生成的,需要进行一些调查找出原因)。$./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:
-
Define the header file (test.h):
#ifndef TEST_H_ #define TEST_H_ char* myprint(char *msg); #endif
-
Define the implementation file (test.c):
#include <stdio.h> #include "test.h" extern void receiveC(char *msg); char* myprint(char *msg) { receiveC(msg); return msg; }
-
Include the
.h
file to thego
file (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() }
-
Build the program :
go build
-
run the generated executable (the executable file generate with the
cgo
name, need some investigation to find the reason).$./cgo
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论