Go 1.5即将发布的版本带有新的构建模式,该模式允许导出Go符号以从C代码进行链接和调用。我一直在研究它,并使用了基本的“ Hello world”示例,但是现在我试图链接一个以a开始的Go库,net/http.Server但它失败了。代码看起来像这样(在此处也可用):
net/http.Server
gohttplib.go:
package main import "C" import "net/http" //export ListenAndServe func ListenAndServe(caddr *C.char) { addr := C.GoString(caddr) http.ListenAndServe(addr, nil) } func main() {}
examples / c / main.c:
#include <stdio.h> #include "../../gohttplib.h" int main() { ListenAndServe(":8000"); return 0; }
产生静态链接的对象和标头可以正常工作:
$ go build -buildmode=c-archive
但是针对它进行编译失败了:
$ gcc -o gohttp-c examples/c/main.c gohttplib.a -lpthread Undefined symbols for architecture x86_64: "_CFArrayGetCount", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) "_CFArrayGetValueAtIndex", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) "_CFDataAppendBytes", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) "_CFDataCreateMutable", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) "_CFDataGetBytePtr", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) __cgo_6dbb806e9976_Cfunc_CFDataGetBytePtr in gohttplib.a(000003.o) (maybe you meant: __cgo_6dbb806e9976_Cfunc_CFDataGetBytePtr) "_CFDataGetLength", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) __cgo_6dbb806e9976_Cfunc_CFDataGetLength in gohttplib.a(000003.o) (maybe you meant: __cgo_6dbb806e9976_Cfunc_CFDataGetLength) "_CFRelease", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) __cgo_6dbb806e9976_Cfunc_CFRelease in gohttplib.a(000003.o) (maybe you meant: __cgo_6dbb806e9976_Cfunc_CFRelease) "_SecKeychainItemExport", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) "_SecTrustCopyAnchorCertificates", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) "_kCFAllocatorDefault", referenced from: _FetchPEMRoots in gohttplib.a(000003.o) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [example-c] Error 1
这使用的是OS X 10.9.5上Go github存储库(38e3427)的最新版本。我了解Go 1.5尚未发布,并且不能保证它能正常运行,但是我出于教育目的这样做,我怀疑我缺少了一些东西。
相关版本:
$ ld -v @(#)PROGRAM:ld PROJECT:ld64-241.9 configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7m armv7em LTO support using: LLVM version 3.5svn $ gcc --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) Target: x86_64-apple-darwin13.4.0 Thread model: posix
原来这个问题在OSX / darwin上存在。要解决此问题,我们需要向-framework CoreFoundation -framework Securitygcc链接命令添加选项。最终命令如下所示:
-framework CoreFoundation -framework Security
$ gcc -o gohttp-c examples/c/main.c gohttplib.a \ -framework CoreFoundation -framework Security -lpthread
在以后的Go版本中,可能会删除此要求。有关此问题的更多讨论,请参见:https://github.com/golang/go/issues/11258