您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“golang與c語言是怎么相互調(diào)用”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學習一下“golang與c語言是怎么相互調(diào)用”這篇文章吧。
以下為一個簡短的例子:
package main // #include <stdio.h> // #include <stdlib.h> /* void print(char *str) { printf("%s\n", str); } */ import "C" import "unsafe" func main() { s := "Hello Cgo" cs := C.CString(s) C.print(cs) C.free(unsafe.pointer(cs)) }
與“正常”的go代碼相比,上述代碼有幾處“特殊”的地方:
在開頭的注釋中出現(xiàn)了c語言頭文件的include字樣
在注釋中定義了c語言函數(shù)print
import了一個名為C的“包”
在main函數(shù)中調(diào)用了上述定義的c語言函數(shù)print
首先,go源碼文件中的c語言代碼是需要用注釋包裹的,就像上面的include頭文件以及print函數(shù)定義;其次,import "C"這個語句是必須的,而且其與上面的c代碼之間不能用空行分隔,必須緊密相連。這里的”C“不是包名,而是一種類似名字空間的概念,或可以理解為偽包,c語言所有語法元素均在該偽包下面;最后,訪問c語法元素時都要在其前面加上偽包前綴,比如C.uint和上面代碼中的C.print、C.free等。
更詳細的在go中調(diào)用c語言的用法可以參考Go與C語言的互操作,本文不再一一細述。
在上面的例子中,c語言是內(nèi)嵌在go代碼中的,如果代碼量更大更復雜的話,這顯然是很不”專業(yè)“的。那么,是否可以將c語言代碼從go代碼中分離出去,單獨定義呢?答案是肯定的,可以通過共享庫的方式實現(xiàn)。
cgo提供了#cgo
指示符可以指定go源碼在編譯后與哪些共享庫進行鏈接。例子如下:
// hello.go package main // #cgo LDFLAGS: -L ./ -lhello // #include <stdio.h> // #include <stdlib.h> // #include "hello.h" import "C" func main() { C.hello() } // hello.c #include "hello.h" void hello() { printf("hello, go\n"); } // hello.h extern void hello();
其中在hello.go中,#cgo
指示符后面添加LDFLAGS: -L ./ -lhello
,作用是在go代碼編譯時,指定在當前目錄查找so庫并進行鏈接。
因此,只需要把hello.c編譯成動態(tài)庫,再編譯go代碼,即可在運行g(shù)o代碼的時候調(diào)用共享庫中的c語言函數(shù)。指令如下:
gcc -fPIC -o libhello.so hello.c
go build -o hello
./hello
與在go中調(diào)用c源碼相比,在c中使用go函數(shù)的場合較少。因為一般來說,采用高級語言作為粘合劑調(diào)用低級語言能充分發(fā)揮各自的特點,而用低級語言調(diào)用高級語言反而有可能降低低級語言的性能優(yōu)勢,在go中,可以使用”export + 函數(shù)名“來導出go函數(shù)為c代碼所用,看一個簡單的例子:
// hello.go package main import "C" import "fmt" // export Go2C func Go2C() { fmt.Println("hello, C") }
可通過go build
的編譯選項,將go代碼編譯成共享庫以供c代碼調(diào)用。注意,編譯so庫時必須存在main及main函數(shù)(即使main函數(shù)為空)。編譯指令如下:go build -v -x -buildmode=c-shared -o libhello.so hello.go
。
編譯成功后,只需在c代碼中引入新生成的頭文件及編譯時鏈接動態(tài)庫即可實現(xiàn)go函數(shù)的調(diào)用。代碼如下:
// hello.c #include <stdio.h> #include "libhello.h" int main() { Go2C(); return 0; }
通過gcc -o hello -L. -lhello
,即可編譯成可執(zhí)行程序。注意,運行前必須確定共享庫運行時查找路徑中存在需要鏈接的共享庫,可通過將so庫路徑放到/usr/lib或者修改環(huán)境變量LD_LIBRARY_PATH。
以上是“golang與c語言是怎么相互調(diào)用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。