日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

cgo的效率 golang_golang CGO FAQ TIPS : cgo 从 C 传递 slice 到 go

發布時間:2024/9/27 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cgo的效率 golang_golang CGO FAQ TIPS : cgo 从 C 传递 slice 到 go 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

cgo 從 C 傳遞 slice 到 go

這里一般會用在c的callback中。

需要加一個wrapper,比直接調用go函數中間多了一個轉換步驟,但方便了許多。

執行流程為,c調用發起 -> c wrapper -> go export

.go:

//export a_function_callback

func a_function_callback(args []C.astruct) {}

.c:

extern void a_function_callback(GoSlice args);

void a_function_callback_c(args *C.astruct) {

GoSlice args_go;

args_go.data = args;

args_go.len = nargs;

args_go.cap = nargs;

return a_function_callback(args_go);

}

這里的GoSlice需要從 export 出來的 .h 中獲取,或者 include 該 .h文件。

也可以直接拷貝過來,注意不要產生類型沖突。

#ifndef GO_CGO_PROLOGUE_H

#define GO_CGO_PROLOGUE_H

typedef long long GoInt64;

typedef GoInt64 GoInt;

typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

#endif

C.CString 的自動化回收方法

一般使用 C.CString 時,定義一個臨時變量存儲結果,使用 defer C.free 回收這個臨時的變量。

在 go 的 runtime 包中,有一個SetFinalizer方法,可以在回收對象的時候調用一個處理函數。

那么我們可以考慮使用它來自動化回收 C.CString產生的臨時變量。

type CString struct {

Ptr *C.char

}

func CCString(s string) *CString {

p := C.CString(s)

this := &CString{Ptr: p}

runtime.SetFinalizer(this, freeCString)

return this

}

func freeCString(cs *CString) {

C.free(unsafe.Pointer(cs.Ptr))

}

在使用的時候,基本能嵌入到調用的位置,不需要顯式定義一個臨時變量并執行 defer C.free。

C.somefunc(CCString(s).Ptr)

注意,只在somefunc不接管傳遞的參數的所有權時調用這種方式,如果somefunc接管了所有權,

而在未來某時間內存被回收了,則會出現程序SEGFAULT崩潰。

這種可能會產生一點runtime效率損失,另外還有額外的內存分配,看情況使用。

bool 類型的轉換處理

在 C 語言中,c99之前 bool 都是定義為 int的,要想轉換為go的bool類型,比較曲折。

var bval_c C.GBoolean

var bval_go bool

if int(bval) == 1 {

bval_go = true

} else {

bval_go = false

}

如果go有三元運算符的話,也可一行代碼實現該轉換,問題是go沒有三元運算符。

一般來說,對其包裝一個簡單的轉換函數比較好,比如 c2gobool(C.GBoolean).

有時候不同的 C 項目中 bool 定義不同,所以一般需要為每個項目定義這么一個函數,而不能放在一個庫中共用。

在 c99 之后,則沒有這個問題,cgo能夠直接判斷是內置的bool類型,能夠直接轉換為go的bool。

var bval_c C._Bool

var bval_go = bool(bval_c)

總結

以上是生活随笔為你收集整理的cgo的效率 golang_golang CGO FAQ TIPS : cgo 从 C 传递 slice 到 go的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。