003-golang 調用外部命令
專注于為中小企業(yè)提供網(wǎng)站設計制作、網(wǎng)站設計服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)三亞免費做網(wǎng)站提供優(yōu)質的服務。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了近1000家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設實現(xiàn)規(guī)模擴充和轉變。
相關函數(shù)
exec包執(zhí)行外部命令,它將os.StartProcess進行包裝使得它更容易映射到stdin和stdout,并且利用pipe連接i/o.
func LookPath(file string) (string, error) //LookPath在環(huán)境變量中查找科執(zhí)行二進制文件,如果file中包含一個斜杠,則直接根據(jù)絕對路徑或者相對本目錄的相對路徑去查找
在用exec包調用的其他進程后如何關閉結束,可以使用context包的機制進行管理,context包的使用詳見:
exec.CommandContext方發(fā)實現(xiàn)了context,通過context可以對exec啟動的進程結束。
隱藏程序自身黑窗口的方法:go build -ldflags="-H windows"
隱藏子進程黑窗口的方法:
工程結構如上圖所示,我們需要實現(xiàn)的目標是在go文件中調用c文件
foo.c如下:
foo.go如下
foo.h如下:
編譯過程如下:
1、先將c文件編譯為.o文件,然后生成動態(tài)鏈接庫.dylib文件
(1) clang -c foo.c
(2 clang -shared foo.o -o libfoo.dylib
2、在上述的動態(tài)鏈接庫生成之后,在foo.go中添加動態(tài)鏈接命令:#cgo LDFLAGS: -L./ -lfoo
需要注意的是
中間不能有空格
直接調用so的函數(shù)cgo應該繞不開吧,我寫過一個銀行的應用程序調用其特色業(yè)務接口,因為接口只支持c和java,我就封裝了一個c的so,然后用cgo調用后寫了一個RPC供遠程的go語言調用,因為RPC只負責信息交互不負責業(yè)務邏輯,所以寫了不到百行,以后基本不用再改。記住雖然go語言自帶gc,但cgo還是要手工釋放內存哦。
直接嵌入c源代碼到go代碼里面
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代碼之間不能有空行
運行結果
$ go build main.go ./main
Hello C: 12
Hello Go
分開c代碼到單獨文件
嵌在一起代碼結構不是很好看,很多人包括我,還是喜歡把兩個分開,放在不同的文件里面,顯得干凈,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來調用庫。
$ 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如何調用第三方語言 go語言用在哪里
分享路徑:http://chinadenli.net/article20/doddsco.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設計公司、定制開發(fā)、面包屑導航、建站公司、網(wǎng)站設計、標簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)