溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go語言兼不兼容c語言

發(fā)布時間:2022-12-27 10:55:35 來源:億速云 閱讀:127 作者:iii 欄目:編程語言

這篇“go語言兼不兼容c語言”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“go語言兼不兼容c語言”文章吧。

go語言兼容c語言;Go語言可以調(diào)用C語言,還能給C語言調(diào)用。Go語言工具包中有一個Cgo命令,它用來處理Go調(diào)用C相關操作;而Go的函數(shù)可以導出給C用,只要在要導出的函數(shù)前面加上“//export funcname”就行了,然后可以使用“go build -buildmode=c-shared -o libxxx.so”命令編譯生成動態(tài)庫和頭文件供C語言中使用。

c語言和golang是兼容的。你用c寫的.c文件是可以被golang引用,直接使用的。

現(xiàn)代的各種高級的編程語言很多都是在C語言之上構(gòu)建的,基本上也都能夠調(diào)用C語言,并且這個在某些情況下也是有這個需求和存在的意義的。Go語言對這方面支持的挺不錯,不光可以調(diào)用C語言,還能給C語言調(diào)用。這篇文章將對相關的內(nèi)容做個說明。

基礎說明

Go語言工具包中有一個Cgo命令,它用來處理Go調(diào)用C相關操作。 我們可以直接使用該命令,也可以在運行或構(gòu)建Go程序時自動調(diào)用它。

Cgo對于C語言的處理本身是依賴系統(tǒng)中C語言相關的編譯工具鏈的,所以需要注意對此的設置,主要是Go的環(huán)境變量設置:

go語言兼不兼容c語言

特別需要注意的是Cgo需要使能,可以使用 go env -w CGO_ENABLED=1 命令來設置。上圖中可以看到一些C編譯時的FLAGS參數(shù),如果有需要也可以進行相應設置調(diào)整。另外上面的 CC CXX 是編譯工具鏈的設置,也可以根據(jù)需求設置調(diào)整。

Go中調(diào)用C

Go中調(diào)用C語言最終在Go中都顯示為名為 C 的偽包, 在Go中 import "C" 行之上以注釋 #include ... 方式來引用C語言相關的庫。 這些被引用的庫中公共的變量和函數(shù)等在Go中會被掛到 C 包中以供使用。下面是個簡單的演示:

go語言兼不兼容c語言

在Go中調(diào)用C只要上面這樣就行了,使用起來還是很方便的。

通常來說C語言程序的項目中除了C語言代碼外可能還有匯編代碼;或者項目也有可能是C/C++混合編程的。這些項目都可以在Go中使用,Cgo會自動識別后綴為 .c .s .S .sx .cc .cpp .cxx 的文件,并調(diào)用對應的編譯器去編譯。

需要注意的是C++中的重載和類方法等C不支持的語法想要在Go中使用都需要用C語言標準函數(shù)包裝一層,使用方法就和C語言中調(diào)用C++一樣。

C中調(diào)用Go

下面測試中如果有問題可以嘗試 go clean 重置項目后再進行。

Go的函數(shù)可以導出給C用,只要在要導出的函數(shù)前面加上 //export funcname 就行了,然后可以使用 go build -buildmode=c-shared -o libxxx.so 命令編譯生成動態(tài)庫和頭文件供C語言中使用:

go語言兼不兼容c語言
go語言兼不兼容c語言

另外也可以使用 go build -buildmode=c-archive -o libxxx.a 編譯生成可用C語言使用的靜態(tài)庫。

數(shù)據(jù)類型差異

兩個語言間調(diào)用其實就是數(shù)據(jù)的傳遞處理,需要注意的是因為兩者畢竟不是同一種語言所以兩者之間可以交互的數(shù)據(jù)類型是有限制的。有些時候也會有強制轉(zhuǎn)換數(shù)據(jù)類型的需求,比如下面這個代碼:

package rand

// #include <stdlib.h>
import "C"

func Random() int {
    return int(C.random()) // C函數(shù)返回值給Go,random的返回值是long類型
}

func Seed(i int) {
    C.srandom(C.uint(i)) // Go傳值給C的函數(shù),srandom函數(shù)接收uint類型數(shù)據(jù)
}

兩者間可用的基本數(shù)值類型轉(zhuǎn)換有下面一些:

C.char,       C.schar (signed char),       C.uchar (unsigned char)
C.short,       C.ushort (unsigned short)
C.int,       C.uint (unsigned int)
C.long,       C.ulong (unsigned long)
C.longlong (long long),       C.ulonglong (unsigned long long)
C.float,       C.double
C.complexfloat (complex float),       C.complexdouble (complex double)

除了上面的基礎類型,指針也是可以傳遞的。特別的C語言中的 void* 指針相當于Go中的 unsafe.Pointer 。

C中的 __int128_t__uint128_t 相當于Go中的 [16]byte 。

C中函數(shù)傳輸參數(shù)為數(shù)組的話直接傳遞數(shù)組名就行,在Go中向這類函數(shù)傳遞數(shù)組需要傳遞數(shù)組第一個元素的地址,另外需要注意的是數(shù)組中元素也必須是C語言中支持的類型:

C.f(&C.arr[0])

C中并沒有string類型,使用字符串時需要進行處理:

package print

// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"

func Print(s string) {
    cs := C.CString(s) // 這個方式會將字符串拷貝一份,返回指針,注意使用完需要釋放內(nèi)存
    defer C.free(unsafe.Pointer(cs)) // defer修飾的語句會在該函數(shù)退出前執(zhí)行
    C.fputs(cs, (*C.FILE)(C.stdout))
}

另外C語言的字符串 *C.char 可以使用 C.GoString() 轉(zhuǎn)換成Go中的字符串。

C中的 struct union enum 這些類型在Go使用需要加上對應的前綴,變成 struct_xxx union_xxx enum_xxx 。其中聯(lián)合體在Go中將成為字節(jié)數(shù)組的形式。這些對象的成員名如果和Go的關鍵詞一樣的話,在Go中使用需要在成員名前面加下劃線,比如 x._name 。

C中的 sizeof 在Go中需要使用 C.sizeof_T 方式使用,T是變量數(shù)據(jù)類型。

以上就是關于“go語言兼不兼容c語言”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關的知識內(nèi)容,請關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI