2015-06-17 8 views
7

W nadchodzącej wersji Go 1.5 pojawi się new buildmodes, które pozwalają eksportować symbole Go do połączenia i wywołania z kodu C. Bawiłem się z nim i otrzymałem podstawowe przykłady "Hello world" działające, ale teraz próbuję połączyć bibliotekę Go, która zaczyna się od net/http.Server i to się nie udaje. Kod wygląda następująco (it's also available here)Używanie Go 1.5 buildmode = c-archive z net/http.Server połączony z C

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

przykłady/c/main.c:

#include <stdio.h> 
#include "../../gohttplib.h" 

int main() 
{ 
    ListenAndServe(":8000"); 
    return 0; 
} 

Wyprodukowanie statycznie połączonego obiektu i nagłówki działają poprawnie:

$ go build -buildmode=c-archive 

Ale kompilacji przed nim się niepowodzeniem:

$ 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 

To jest za pomocą najnowszej wersji z repozytorium Go github (38e3427) na OS X 10.9.5. Rozumiem, że wersja Go 1.5 nie jest jeszcze wydana i że nie ma żadnych gwarancji, że działa, ale robię to dla celów edukacyjnych i podejrzewam, że czegoś brakuje.

Powiązane wersje:

$ 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 
+0

Działa dla mnie w wersji 'a2aaede' i Ubuntu 14.04. Czy próbowałeś dokonać aktualizacji do nowszej wersji deweloperskiej? –

+0

Wyciągnął "a2aaede", ten sam problem dla mnie. Być może w jakiś sposób wiąże się z OSX, chociaż gcc-5 zawodzi w podobny sposób. – shazow

+0

Może to być warte [otwórz problem] (https://github.com/golang/go/issues/new) na ten temat. –

Odpowiedz

7

okazuje ten problem istnieje na OSX/Darwin. Aby obejść ten problem, musimy dodać opcję -framework CoreFoundation -framework Security do polecenia łączenia gcc. Końcowe polecenie wygląda następująco:

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

To wymaganie może zostać usunięte w przyszłej wersji aplikacji Go. Więcej dyskusji na ten temat tutaj: https://github.com/golang/go/issues/11258