直接嵌入c源代碼到go代碼里面
成都創(chuàng)新互聯(lián)長期為近1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為豐滿企業(yè)提供專業(yè)的網(wǎng)站設(shè)計制作、網(wǎng)站制作,豐滿網(wǎng)站改版等技術(shù)服務(wù)。擁有10年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
package main
/*
#include stdio.h
void myhello(int i) {
printf("Hello C: %d\n", i);
}
*/
import "C"
import "fmt"
func main() {
C.myhello(C.int(12))
fmt.Println("Hello Go");
}
需要注意的是C代碼必須放在注釋里面
import "C"語句和前面的C代碼之間不能有空行
運行結(jié)果
$ go build main.go ./main
Hello C: 12
Hello Go
分開c代碼到單獨文件
嵌在一起代碼結(jié)構(gòu)不是很好看,很多人包括我,還是喜歡把兩個分開,放在不同的文件里面,顯得干凈,go源文件里面是go的源代碼,c源文件里面是c的源代碼。
$ ls
hello.c hello.h main.go
$ cat hello.h
void hello(int);
$ cat hello.c
#include stdio.h
void hello(int i) {
printf("Hello C: %d\n", i);
}
$ cat main.go
package main
// #include "hello.h"
import "C"
import "fmt"
func main() {
C.hello(C.int(12))
fmt.Println("Hello Go");
}
編譯運行
$ go build ./main
Hello C: 12
Hello Go
編譯成庫文件
如果c文件比較多,最好還是能夠編譯成一個獨立的庫文件,然后go來調(diào)用庫。
$ find mylib main
mylib
mylib/hello.h
mylib/hello.c
main
main/main.go
編譯庫文件
$ cd mylib
# gcc -fPIC -shared -o libhello.so hello.c
編譯go程序
$ cd main
$ cat main.go
package main
// #cgo CFLAGS: -I../mylib
// #cgo LDFLAGS: -L../mylib -lhello
// #include "hello.h"
import "C"
import "fmt"
func main() {
C.hello(C.int(12))
fmt.Println("Hello Go");
}
$ go build main.go
運行
$ export LD_LIBRARY_PATH=../mylib
$ ./main
Hello C: 12
Hello Go
在我們的例子中,庫文件是編譯成動態(tài)庫的,main程序鏈接的時候也是采用的動態(tài)庫
$ ldd main
linux-vdso.so.1 = (0x00007fffc7968000)
libhello.so = ../mylib/libhello.so (0x00007f513684c000)
libpthread.so.0 = /lib64/libpthread.so.0 (0x00007f5136614000)
libc.so.6 = /lib64/libc.so.6 (0x00007f5136253000)
/lib64/ld-linux-x86-64.so.2 (0x000055d819227000)
理論上講也是可以編譯成整個一靜態(tài)鏈接的可執(zhí)行程序,由于我的機器上缺少靜態(tài)鏈接的系統(tǒng)庫,比如libc.a,所以只能編譯成動態(tài)鏈接。
不可能。Go到目前為止,其本身就是用C寫的。只是在語言層面實現(xiàn)了一些如果用C會很難寫的feature,比如goroutine。在1.5版本中,Go會bootstraping,用Go來編譯自己。
C語言,幾乎每種操作系統(tǒng)的系統(tǒng)調(diào)用都是C,C最大的作用就是用來實現(xiàn)新的語言。
Go是一個圖靈完備的語言
任何圖靈完備的語言理論上都可以用來編譯自身。比如c/c++, java, vb, php等等都可以。
至于怎么編譯自身的:
用其它語言比如c++實現(xiàn)一個[Go語言編譯器-1]
用Go語言寫一個[Go語言編譯器-2]
用這個c++實現(xiàn)的[Go語言編譯器-1]編譯第2步里面說的Go語言寫的[Go語言編譯器-2]
用第3步得到的[Go語言編譯器-2],再編譯一次第2步里面說的[Go語言編譯器-2]的源碼。
OK,現(xiàn)在有一個Go語言實現(xiàn)的編譯器了,最開始那個c++寫的編譯器沒用了,可以扔掉不要了。以后就不停的優(yōu)化使用這個Go語言實現(xiàn)的自身的編譯器就行了。