首頁 >後端開發 >Golang >go語言相容c語言嗎

go語言相容c語言嗎

青灯夜游
青灯夜游原創
2022-12-26 10:23:045615瀏覽

go語言相容c語言;Go語言可以呼叫C語言,也能給C語言呼叫。 Go語言工具包中有一個Cgo指令,它用來處理Go呼叫C相關運算;而Go的函式可以匯出到C用,只要在要匯出的函式前面加上「//export funcname」就行了,然後可以使用「go build -buildmode=c-shared -o libxxx.so」指令編譯產生動態函式庫和頭檔供C語言中使用。

go語言相容c語言嗎

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

c語言和golang是相容的。你用c寫的.c檔是可以被golang引用,直接用的。

現代的各種高階的程式語言很多都是在C語言之上建構的,基本上也都能夠呼叫C語言,而這個在某些情況下也是有這個需求和存在的意義的。 Go語言對這方面支援的挺不錯,不光可以呼叫C語言,還能給C語言呼叫。這篇文章將對相關的內容做個說明。

基礎說明

Go語言工具包中有一個Cgo指令,它用來處理Go呼叫C相關運算。我們可以直接使用該命令,也可以在執行或建置Go程式時自動呼叫它。

Cgo對於C語言的處理本身是依賴系統中C語言相關的編譯工具鏈的,所以需要注意對此的設置,主要是Go的環境變數設定:

go語言相容c語言嗎

#特別要注意的是Cgo需要使能,可以使用go env -w CGO_ENABLED=1 指令來設定。上圖中可以看到一些C編譯時的FLAGS參數,如果有需要也可以進行對應設定調整。另外上面的 CC CXX 是編譯工具鏈的設置,也可以依照需求設定調整。

Go中呼叫C

Go中呼叫C語言最終在Go中都顯示為名為C 的偽包, 在Go中import "C" 行之上以註解#include ... 方式來引用C語言相關的函式庫。 這些被引用的庫中公共的變數和函數等在Go中會被掛到 C 套件中以供使用。下面是個簡單的示範:

go語言相容c語言嗎

在Go中呼叫C只要上面這樣就行了,使用起來還是很方便的。

通常來說C語言程式的專案中除了C語言程式碼外可能還有彙編程式碼;或者專案也有可能是C/C 混合程式設計的。這些項目都可以在Go中使用,Cgo會自動辨識後綴為.c .s .S .sx . cc .cpp .cxx 的文件,並呼叫對應的編譯器去編譯。

要注意的是C 中的重載和類別方法等C不支援的語法想要在Go中使用都需要用C語言標準函數包裝一層,使用方法就和C語言中呼叫C一樣。 【相關推薦:在Go影片教學程式設計教學

C中呼叫Go

#下面測試中如果有問題可以嘗試go clean 重置專案後再進行。

Go的函數可以匯出給C用,只要在要匯出的函式前面加上//export funcname 就行了,然後可以使用go build -buildmode =c-shared -o libxxx.so 指令編譯產生動態函式庫和頭檔在C語言中使用:

go語言相容c語言嗎
go語言相容c語言嗎

##另外也可以使用

go build -buildmode=c-archive -o libxxx.a 編譯產生可用C語言使用的靜態函式庫。

資料型別差異

兩個語言間呼叫其實就是資料的傳遞處理,需要注意的是因為兩者畢竟不是同一種語言所以兩者之間可以互動的資料類型是有限制的。有些時候也會有強制轉換資料型別的需求,例如下面這個程式碼:

package rand

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

func Random() int {
    return int(C.random()) // C函数返回值给Go,random的返回值是long类型
}

func Seed(i int) {
    C.srandom(C.uint(i)) // Go传值给C的函数,srandom函数接收uint类型数据
}

兩者間可用的基本數值型別轉換有下面一些:

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中函数传输参数为数组的话直接传递数组名就行,在Go中向这类函数传递数组需要传递数组第一个元素的地址,另外需要注意的是数组中元素也必须是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) // 这个方式会将字符串拷贝一份,返回指针,注意使用完需要释放内存
    defer C.free(unsafe.Pointer(cs)) // defer修饰的语句会在该函数退出前执行
    C.fputs(cs, (*C.FILE)(C.stdout))
}

另外C语言的字符串 *C.char 可以使用 C.GoString() 转换成Go中的字符串。

C中的 struct union enum 这些类型在Go使用需要加上对应的前缀,变成 struct_xxx union_xxx enum_xxx 。其中联合体在Go中将成为字节数组的形式。这些对象的成员名如果和Go的关键词一样的话,在Go中使用需要在成员名前面加下划线,比如 x._name

C中的 sizeof 在Go中需要使用 C.sizeof_T 方式使用,T是变量数据类型。

更多编程相关知识,请访问:编程视频!!

以上是go語言相容c語言嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn