cgo的踩坑記及乙個簡單的例子

2021-09-21 13:20:38 字數 2501 閱讀 4690

首先,來看 golang 和 c 的型別轉換對照表:

c語言型別

cgo型別

go語言型別

char

c.char

byte

singed char

c.schar

int8

unsigned char

c.uchar

uint8

short

c.short

int16

unsigned short

c.ushort

uint16

intc.int

int32

unsigned int

c.uint

uint32

long

c.long

int32

unsigned long

c.ulong

uint32

long long int

c.longlong

int64

unsigned long long int

c.ulonglong

uint64

float

c.float

float32

double

c.double

float64

size_t

c.size_t

uint

值得注意的是,c 中的整形比如 int 在標準中是沒有定義具體字長的,但一般預設認為是 4 位元組,對應 cgo 型別中 c.int 則明確定義了字長是 4 ,但 golang 中的 int 字長則是 8 ,因此對應的 golang 型別不是 int 而是 int32 。為了避免誤用,c **最好使用 c99 標準的數值型別,對應的轉換關係如下:

c語言型別

cgo型別

go語言型別

int8_t

c.int8_t

int8

uint8_t

c.uint8_t

uint8

int16_t

c.int16_t

int16

uint16_t

c.uint16_t

uint16

int32_t

c.int32_t

int32

uint32_t

c.uint32_t

uint32

int64_t

c.int64_t

int64

uint64_t

c.uint64_t

uint64

在go中呼叫c一共有兩種辦法:

第一種實現起來比較順滑,如絲一般,但是沒有進行分資料夾管理,看上去很不爽,同時也隱藏了乙個坑,直接看乙個栗子:

package main

/*#include static int32_t add(int32_t a, int32_t b)

*/import "c"

import "fmt"

func main()

如果在c**與「import 「c」」之間留乙個空行,直接報錯如下:

去掉空行後就ok啦~,結果如下:

第二種實現實現起來坑就大大的了,no bb, 直接上栗子:

佛曰:眾生都是這麼幹的,一般分為兩步:

但在第二步的編譯過程中會出現如下「對foo未定義的引用「的錯誤:

於是乎,趕緊引經據典,經過一番折騰之後,在最終找到了答案:

我們不需要手動地給go提供動態鏈結庫,甚至於go根本不認識我們自己手動編譯出的動態鏈結庫。其實cgo提供了一種機制:它能夠根據import」c」中引入的標頭檔案,自動找到相應的原始檔進行編譯鏈結。這種機制的呼叫,需要用到go build命令。

輸出結果如下:

佛曰:眾生皆幻象,眾生皆平等!

記乙個ArrayList set 的坑

在專案中遇到需要把arraylist的第乙個位置覆蓋成新的值 而恰巧第乙個位置沒有任何值,然後就拋越位異常了 arraylistobjects new arraylist objects.set 0,1 arraylist set public e set int index,e element a...

最近踩的乙個小坑

最近需要實現乙個業務,大致的內容是為了提高效率,把資料庫中的資訊定時同步到記憶體中,然後使用記憶體查詢,提高效率。然後在實現過程中遇到了乙個問題,需要同步的資訊約9萬條,但是這9w條資料對應了133w個,大概乙個id十幾張吧。儲存這些的時候,遇到了小問題。專案原本使用的結構是 list vin1,1...

golang新版本對於cgo支援的乙個坑

檔案test.h如下 ifndef test h define test h ifdef cplusplus extern c endif endif 檔案test.cc如下 include cgo export.h extern c 檔案test.go如下 package test include...