当前位置: 首页 > 面试题库 >

使用Go 1.5 buildmode = c-archive与从C链接的net / http.Server

魏勇军
2023-03-14
问题内容

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() {}

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链接命令添加选项。最终命令如下所示:

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

在以后的Go版本中,可能会删除此要求。有关此问题的更多讨论,请参见:https://github.com/golang/go/issues/11258



 类似资料:
  • 我试图使用Xcode5.0Objective-C项目中的libtorrent库,但没有成功。 我使用LLVM5.0从源代码中构建了boost 1.54和libtorrent-rasterbar(最新),没有任何问题。此外,通过MacPorts,我获得了pkg-config以获得libtorrent-rasterbar库的适当cflags。从我的生成设置中,pkgconfig库和cflags的输出为

  • 问题内容: 我是C#和.NET的新手,但是我编写了此代码来调用存储过程,然后我想获取返回的DataTable并将其转换为JSON。 那么我的问题是最好/最简单的方法是什么?一个例子很好,因为我对此还很陌生。 问题答案: 代替数据表,您应该使用数据读取器。您的代码效率低下,而且有点难以阅读-您可能需要执行以下操作: 然后,您可以使用该信息

  • 本文向大家介绍C#.Net ArrayList的使用方法,包括了C#.Net ArrayList的使用方法的使用技巧和注意事项,需要的朋友参考一下 ArrayList就是传说中的动态数组,它提供了如下一些好处: 动态的增加和减少元素 实现了ICollection和IList接口 灵活的设置数组的大小 1、如何使用ArrayList 最简单的例子: 这是一个简单的例子,虽然没有包含ArrayList

  • Net-C 是一个跨平台的局域网聊天工具,支持表情、私信,设置用户状态、群组聊天等功能。 主界面如下图所示

  • 我有一个项目要用C#使用Selenium WebDriver点击web页面上的特定链接,我正在努力找到一种干净的方法,用一个数组来迭代这些链接,以说明特定的情况。 所以总结一下: 需要帮助找到一种方法来创建一个数组,可以在循环中找到要单击的特定链接,因为在搜索了一段时间后,这似乎是最整洁的解决方案。如果有更好的建议,我愿意接受。只是对C#/Selenium完全陌生。

  • 我想知道是否有任何方法可以在我的Udp客户端接收数据时以某种方式触发事件?(System. Net. Socket. Udp客户端) 我尝试覆盖它的 UdpClient.Receive,但我不能根据这个,因为可覆盖的成员必须标记为虚拟或抽象。 我目前的做法是在Threading.Timer上运行一个TimerCallback,以特定的时间间隔来获取我的数据,但我更愿意在传入数据到达时接收它,而不是