2015-08-25 25 views
29

Hedef 1.5'ten bu yana, onu mevcut bir projeme nasıl entegre edebileceğime bir bakmaya başladım.Varolan bir C projesinde Go kodunu kullanma

Projenin kod tabanı, donanım ve diğer eğlenceli öğelere düşük düzeyde erişim için tamamen C dilinde yazılmıştır. Ancak, bazı üst düzey şeyler sıkıcıdır ve bunları daha yüksek bir dilde yazmaya başlamak istiyorum (Go)

Bir C programından Go kodunu çağırabilirmiyim? Çalışmaya çalıştığım -buildmode=c-archive (https://golang.org/s/execmodes) ekleyen Go 1.5'i yükledim. Ancak, projemin gerçekten derlenmesini sağlamak için uygun üstbilgi dosyalarını üretmek için Git'i göremiyorum. Arşivi oluşturduğumda, verilen sembollerde (objdump kullanarak) işlevi görüyorum, ancak gcc'nin içerdiği fonksiyon hakkında eksiklik içermiyor (beklendiği gibi)

Gitmek için oldukça yeniyim - ancak Dili seviyorum ve bundan yararlanmak istiyorum. Birbiriyle güzelce oynaması için herhangi bir deyim var mı ("deyimsiz" Go Go dünyasında çok şey kullanır)?

Bu soruyu sordu ve özellikle Git 1.5 sözü neden bu belgeye göre, https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5ytjfcoke Git 1.5 Git kodu çağıracak programları olmayan Go desteği eklendi olmasıdır. Spesifik olarak, "Git olmayan bir programa bağlanan ve aranan Git kodu" bölümü altında belirtilen "

+1

Cgo ile ihracat yapıyor musunuz? Bağlayacağınız belge şöyle diyor: "Yalnızca değiştirilebilir semboller [cgo dokümanları] 'nda açıklandığı gibi (herhangi bir paket tarafından) işaretlenenler olacaktır (https://golang.org/cmd/cgo/#hdr-C_references_to_Go) ." Cgo dokümantasyonuna yapılan link, oluşturulan bir _cgo_export.h'den bahseder. –

+1

Daha önce bir soru, cevabın hayır olduğunu söyledi. 1.5'de bir şey değiştiyse merak ediyorum ama şüphem var: http://stackoverflow.com/questions/6125683/call-go-functions-from-c –

+2

Go 1.5'den bahsettiğim nedeni, bu belgenin özellikle Bu kodda beklemediğiniz sistemler tarafından çağrılan paylaşılan nesne dosyaları veya arşiv dosyaları oluşturabileceğinden bahseder. Bu kodun içinde "Git kodlu bir programa bağlanan ve aranan Git kodu" bölümü altında işaretlenir. https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5ytjfcoke – dreadiscool

cevap

42

" dan C'ye göre bir arşiv oluşturmak için bunları dışa aktarılan CGo sembolleri olarak işaretlemeniz gerekir. Aşağıdaki içeriğe sahip bir dosya foo.go oluşturmak Örneğin
: nota

package main 

import (
    "C" 
    "fmt" 
) 

//export PrintInt 
func PrintInt(x int) { 
    fmt.Println(x) 
} 

func main() {} 

önemli şeyler şunlardır:

  • paket Sen olmalı
  • main çağrılması gerekir main işlevi, boş olabilir, ancak.
  • Sen C
  • Sen şu komutla C çağrılabilir statik kütüphane olarak alınabilir veya siz

C çağrılabilir istediğiniz işlevleri işaretlemek için özel //export yorumlarınıza ihtiyacım paketi ithalat gerekir:

go build -buildmode=c-archive foo.go 

sonuç bir arşiv foo.a ve bir başlık foo.h olacaktır. başlığında, şu (eliding alakasız parçaları) olsun:

... 
typedef long long GoInt64; 
... 
typedef GoInt64 GoInt; 
... 
extern void PrintInt(GoInt p0); 
... 

Böylece ihraç işlevi çağırmak için yeterli.

#include "foo.h" 

int main(int argc, char **argv) { 
    PrintInt(42); 
    return 0; 
} 

Biz böyle bir komutla derleyebilirsiniz: Git çalışma zamanı parçacığı kullanımını kolaylaştırır, çünkü

gcc -pthread foo.c foo.a -o foo 

-pthread seçenek gereklidir Biz şöyle diyor basit bir C programını yazabilir.Ortaya çıkan yürütülebilir dosyayı çalıştırdığımda, 42'u yazdırır.

+0

misc question: OSX'ten pencereler için çapraz derleme yaparken bunu çalışması için herhangi bir yolu var mı? Bu bölüm başarısız olacak: '' 'GOOS = windows GOARCH = amd64 go build -buildmode = c-arşivi foo.go''' – mwag

+0

IIRC, CGo çapraz oluşturma sırasında varsayılan olarak devre dışı bırakılır. "CGO_ENABLED = 1" ile yeniden etkinleştirebilirsiniz, ancak https://golang.org/cmd/ adresinde açıklandığı gibi "CC_FOR_TARGET" ve "CXX_FOR_TARGET" ile de hedef kemer için C/C++ derleyicileri sağlamanız gerekir. CGO /. Yine de OSX'de Windows için bina için özel bir tavsiyem yok. –

+0

Harika cevap! (derhal işaretli) – PiersyP