如何在golang中呼叫c的靜態庫或者動態庫

時間 2021-06-25 11:59:27

1樓:匿名使用者

1. 無論呼叫動態庫還是靜態庫都只需要include庫的標頭檔案就可以了

2. 要在呼叫該靜態庫的地方新增庫引用,並設定路徑。

結論:其實靜態庫呼叫動態庫或者靜態庫,只是在用到庫方法的地方把該方法新增到lib當中,真正使用的地方才會把這些庫link起來生成可執行檔案。

2樓:匿名使用者

cgo 使得go程式能夠呼叫c**. cgo讀入一個用特別的格式寫的go語言原始檔, 輸出go和c程式, 使得c程式能打包到go語言的程式包中.

舉例說明一下. 下面是一個go語言包, 包含了兩個函式 -- random 和 seed -- 是c語言庫中random和srandom函式的馬甲.

package rand

/*#include

*/ import "c" func random() int func seed(i int)

我們來看一下這裡都有什麼內容. 開始是一個包的匯入語句.

rand包匯入了"c"包, 但你會發現在go的標準庫裡沒有這個包. 那是因為c是一個"偽包", 一個為cgo引入的特殊的包名, 它是c名稱空間的一個引用.

rand 包包含4個到c包的引用: 呼叫 c.random和c.srandom, 型別轉換 c.uint(i)還有引用語句.

random函式呼叫libc中的random函式, 然後回返結果. 在c中, random返回一個c型別的長整形值, cgo把它輪換為c.long.

這個值必需轉換成go的型別, 才能在go程式中使用. 使用一個常見的go型別轉換:

func random() int

這是一個等價的函式, 使用了一個臨時變數來進行型別轉換:

func random() int

seed函式則相反. 它接受一個go語言的int型別, 轉換成c語言的unsigned int型別, 然後傳遞給c的srandom函式.

func seed(i int)

需要注意的是, cgo中的unsigned int型別寫為c.uint; cgo的文件中有完整的型別列表.

這個例子中還有一個細節我們沒有說到, 那就是匯入語句上面的註釋.

/*#include

*/ import "c"

cgo可以識別這個註釋, 並在編譯c語言程式的時候將它當作一個標頭檔案來處理. 在這個例子中, 它只是一個include語句, 然而其實它可以是使用有效的c語言**. 這個註釋必需緊靠在import "c"這個語句的上面, 不能有空行, 就像是文件註釋一樣.

strings and things

與go語言不同, c語言中沒有顯式的字串型別. 字串在c語言中是一個以0結尾的字元陣列.

go和c語言中的字串轉換是通過c.cstring, c.gostring,和c.gostringn這些函式進行的. 這些轉換將得到字串型別的一個副本.

下一個例子是實現一個print函式, 它使用c標準庫中的fputs函式把一個字串寫到標準輸出上:

package print // #include // #include import "c" import "unsafe" func print(s string)

在c程式中進行的記憶體分配是不能被go語言的記憶體管理器感知的. 當你使用c.cstring建立一個c字串時(或者其它型別的c語言記憶體分配), 你必需記得在使用完後用c.

free來釋放它.

呼叫c.cstring將返回一個指向字元陣列開始處的指錯, 所以在函式退出前我們把它轉換成一個unsafe.pointer(go中與c的void 等價的東西), 使用c.

free來釋放分配的記憶體. 一個慣用法是在分配記憶體後緊跟一個defer(特別是當這段**比較複雜的時候), 這樣我們就有了下面這個print函式:

func print(s string)

構建 cgo 包

如果你使用goinstall, 構建cgo包就比較容易了, 只要呼叫像平常一樣使用goinstall命令, 它就能自動識別這個特殊的import "c", 然後自動使用cgo來編譯這些檔案.

如果你想使用go的makefiles來構建, 那在cgofiles變數中列出那些要用cgo處理的檔案, 就像gofiles變數包含一般的go原始檔一樣.

rand包的makefile可以寫成下面這樣:

include $(goroot)/src/make.inc

targ=goblog/rand

cgofiles=\ rand.go\ include $(goroot)/src/make.pkg

然後輸入gomake開始構建.

更多 cgo 的資源

cgo的文件中包含了關於c偽包的更多詳細的說明, 以及構建過程. go**樹中的cgo的例子給出了更多更高階的用法.

一個簡單而又符合go慣用法的基於cgo的包是russ cox寫的gosqlite. 而go語言的**上也列出了更多的的cgo包.

最後, 如果你對於cgo的內部是怎麼運作這個事情感到好奇的話, 去看看執行時包的cgocall.c檔案的註釋吧.

如何在c中webservice呼叫方法總結

一騎當後 一 webservice在cs後臺程式中的呼叫 a 通過名稱空間和類名直接呼叫 示例 webservice ws new webservice string s ws.helloworld b 通過新增web引用的方式呼叫,首先新增web引用,通過url指向webservice,指定web...

如何在matlab中呼叫matlab中已有的函式

呼叫函式檔案 myfile.m clear clcfor t 1 10 y mylfg t end 自定義函式檔案 mylfg.m function y mylfg x 注意 函式名 mylfg 必須與檔名 mylfg.m 一致 y x 1 3 注 這種方法要求自定義函式必須單獨寫一個m檔案,不能與...

c語言結構體如何在多個原始檔裡面呼叫

foo.件裡面寫 ifndef foo h define foo h struct foo endif 然後每一個需要這個結構體的檔案都加標頭檔案 foo.h 標頭檔案裡用extern struct 其中一個.c檔案裡 struct 其他.c要用的話吧這個標頭檔案包含進去。 引用結構體有引用型別,和...