直接嵌入c源代碼到go代碼里面
門源網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),門源網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為門源上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的門源做網(wǎng)站的公司定做!
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代碼之間不能有空行
運(yùn)行結(jié)果
$ go build main.go ./main
Hello C: 12
Hello Go
分開c代碼到單獨(dú)文件
嵌在一起代碼結(jié)構(gòu)不是很好看,很多人包括我,還是喜歡把兩個(gè)分開,放在不同的文件里面,顯得干凈,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");
}
編譯運(yùn)行
$ go build ./main
Hello C: 12
Hello Go
編譯成庫文件
如果c文件比較多,最好還是能夠編譯成一個(gè)獨(dú)立的庫文件,然后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
運(yùn)行
$ export LD_LIBRARY_PATH=../mylib
$ ./main
Hello C: 12
Hello Go
在我們的例子中,庫文件是編譯成動(dòng)態(tài)庫的,main程序鏈接的時(shí)候也是采用的動(dòng)態(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)
理論上講也是可以編譯成整個(gè)一靜態(tài)鏈接的可執(zhí)行程序,由于我的機(jī)器上缺少靜態(tài)鏈接的系統(tǒng)庫,比如libc.a,所以只能編譯成動(dòng)態(tài)鏈接。
Go 語言和 C 語言的一個(gè)很大的區(qū)別是, Go 語言只靜態(tài)編譯,做個(gè)測試:
一方面是 Go 語言編譯后的可執(zhí)行文件大小比 C 語言的大很多,
另一方面是 C 語言的可執(zhí)行文件需要依賴 glibc 動(dòng)態(tài)庫,
用 ldd 命令可以看出來:
或者直接刪除 glibc 動(dòng)態(tài)庫, C 可執(zhí)行程序報(bào)錯(cuò),而 Go 的還能運(yùn)行:
這時(shí)候只有內(nèi)部命令可以運(yùn)行,外部命令,包括 ln 甚至最常用的 ls 命令也不能運(yùn)行了:
設(shè)置好 LD_PRELOAD 環(huán)境變量之后, ln 命令可以運(yùn)行,但是 sudo 仍然不能運(yùn)行
只能靠 root 用戶來重新創(chuàng)建軟連接了:
所以用 sudo 來 rm 文件要小心,還是用 root 比較好。如果沒有預(yù)先留一個(gè)打開的 root 終端,登錄都登不進(jìn)去。
第一種:LiteIDE
LiteIDE是一個(gè)簡單的開源IDE,值得注意的是,它是GO語言2012年正式版發(fā)布的首個(gè)IDE,由Qt開發(fā),它看起來類似于Visual Studio等其他編譯器。
由于它是為golang設(shè)計(jì)的,LiteIDE為開發(fā)人員提供了許多有用的功能,包括可配置的構(gòu)建命令,高級(jí)代碼編輯器和廣泛的golang支持。其他功能包括代碼管理、gdb、Delve調(diào)試器、自動(dòng)完成和使用WordApi的主題,基于MIME類型的系統(tǒng)等。
第二種:VS Code
它是微軟開發(fā)的廣受歡迎的開源IDE,有一個(gè)開箱即用的go擴(kuò)展可供VS Code使用。VS Code插件為開發(fā)人員提供了很多功能,包括與許多go工具集成。
VS Code通過IntelliSense,內(nèi)置git集成,直接從編譯器調(diào)試代碼等功能提供智能完成功能;VS Code具有高度可擴(kuò)展性,并通過其許多擴(kuò)展提供了許多自定義選項(xiàng),還提供了幾十種語言的支持,成為受開發(fā)者歡迎的工具。
第三種:Atom
開發(fā)人員可以利用這個(gè)Atom IDE改進(jìn)的語言集成與更智能的編輯器。開源的go-plus軟件包使開發(fā)人員更容易在GO中進(jìn)行編程。
Atom和go-plus軟件包為golang提供工具,構(gòu)建流程,linters、vet和coverage工具的支持;其他功能包括自動(dòng)完成、格式化、測試和文檔。
第四種:Vim
Vim有許多插件可以幫助開發(fā)人員更輕松地編輯他們的GO代碼;Vim-go插件自動(dòng)安裝所有必要的東西,為Vim中的GO開發(fā)人員提供更平滑的集成。
Vim-go具有許多有用的功能,包括編譯器,改進(jìn)的語法高亮和折疊,完成支持以及一系列具有集成支持的調(diào)試程序。還有一些使用的高級(jí)源分析工具,包括GoImplements、GoCallees和GoReferrers。