亚洲一级免费看,特黄特色大片免费观看播放器,777毛片,久久久久国产一区二区三区四区,欧美三级一区二区,国产精品一区二区久久久久,人人澡人人草

C語言

Go與C語言的操作

時(shí)間:2025-02-15 15:11:39 C語言 我要投稿
  • 相關(guān)推薦

Go與C語言的操作

  Go有強(qiáng)烈的C背景,除了語法具有繼承性外,其設(shè)計(jì)者以及其設(shè)計(jì)目標(biāo)都與C語言有著千絲萬縷的聯(lián)系。在Go與C語言互操作(Interoperability)方面,Go更是提供了強(qiáng)大的支持。尤其是在Go中使用C,你甚至可以直接在Go源文件中編寫C代碼,這是其他語言所無法望其項(xiàng)背的。下面是小編為大家?guī)淼腉o與C語言的操作的知識,歡迎閱讀。

  一、Go調(diào)用C代碼的原理

  下面是一個(gè)短小的例子:

  復(fù)制代碼

  package main

  // #include

  // #include

  /*

  void print(char *str) {

  printf("%s ", str);

  }

  */

  import "C"

  import "unsafe"

  func main() {

  s := "Hello Cgo"

  cs := C.CString(s)

  C.print(cs)

  C.free(unsafe.Pointer(cs))

  }

  復(fù)制代碼

  與"正常"Go代碼相比,上述代碼有幾處"特殊"的地方:

  1) 在開頭的注釋中出現(xiàn)了C頭文件的include字樣

  2) 在注釋中定義了C函數(shù)print

  3) import的一個(gè)名為C的"包"

  4) 在main函數(shù)中居然調(diào)用了上述的那個(gè)C函數(shù)-print

  沒錯(cuò),這就是在Go源碼中調(diào)用C代碼的步驟,可以看出我們可直接在Go源碼文件中編寫C代碼。

  首先,Go源碼文件中的C代碼是需要用注釋包裹的,就像上面的include 頭文件以及print函數(shù)定義;

  其次,import "C"這個(gè)語句是必須的,而且其與上面的C代碼之間不能用空行分隔,必須緊密相連。這里的"C"不是包名,而是一種類似名字空間的概念,或可以理解為偽包,C語言所有語法元素均在該偽包下面;

  最后,訪問C語法元素時(shí)都要在其前面加上偽包前綴,比如C.uint和上面代碼中的C.print、C.free等。

  我們?nèi)绾蝸砭幾g這個(gè)go源文件呢?其實(shí)與"正常"Go源文件沒啥區(qū)別,依舊可以直接通過go build或go run來編譯和執(zhí)行。但實(shí)際編譯過程中,go調(diào)用了名為cgo的工具,cgo會識別和讀取Go源文件中的C元素,并將其提取后交給C編譯器編譯,最后與Go源碼編譯后的目標(biāo)文件鏈接成一個(gè)可執(zhí)行程序。這樣我們就不難理解為何Go源文件中的C代碼要用注釋包裹了,這些特殊的語法都是可以被Cgo識別并使用的。

  二、在Go中使用C語言的類型

  1、原生類型

  * 數(shù)值類型

  在Go中可以用如下方式訪問C原生的數(shù)值類型:

  復(fù)制代碼

  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

  復(fù)制代碼

  Go的數(shù)值類型與C中的數(shù)值類型不是一一對應(yīng)的。因此在使用對方類型變量時(shí)少不了顯式轉(zhuǎn)型操作,如Go doc中的這個(gè)例子:

  復(fù)制代碼

  func Random() int {

  return int(C.random())//C.long -> Go的int

  }

  func Seed(i int) {

  C.srandom(C.uint(i))//Go的uint -> C的uint

  }

  復(fù)制代碼

  * 指針類型

  原生數(shù)值類型的指針類型可按Go語法在類型前面加上*,比如var p *C.int。而void*比較特殊,用Go中的unsafe.Pointer表示。任何類型的指針值都可以轉(zhuǎn)換為unsafe.Pointer類型,而unsafe.Pointer類型值也可以轉(zhuǎn)換為任意類型的指針值。unsafe.Pointer還可以與uintptr這個(gè)類型做相互轉(zhuǎn)換。由于unsafe.Pointer的指針類型無法做算術(shù)操作,轉(zhuǎn)換為uintptr后可進(jìn)行算術(shù)操作。

  * 字符串類型

  C語言中并不存在正規(guī)的字符串類型,在C中用帶結(jié)尾'