7

即将发布的 Go 1.5 带有新的构建模式,允许导出 Go 符号以从 C 代码链接和调用。我一直在玩它,并得到了基本的“Hello world”示例,但现在我正在尝试链接一个启动 a 的 Go 库,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() {}

示例/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
4

1 回答 1

8

原来这个问题存在于 OSX/darwin 上。为了解决这个问题,我们需要-framework CoreFoundation -framework Security在 gcc 链接命令中添加选项。最终命令如下所示:

$ gcc -o gohttp-c examples/c/main.c gohttplib.a \
      -framework CoreFoundation -framework Security -lpthread

在 Go 的未来版本中可能会删除此要求。更多关于这个问题的讨论:https ://github.com/golang/go/issues/11258

于 2015-06-17T18:42:42.533 回答