本文主要記錄一些之前在專案中使用cgo呼叫c語言的方法和遇到的一些問題。
在go檔案中寫c**
使用cgo時需要先import 「c」,然後在上面的注釋部分內(/…/)寫c**。其中可以通過cflags和ldflags來指定編譯引數。如下**。
package main
/*#cgo cflags: -i.
#cgo ldflags: -l.
#include void print_something()
*/import
"c"func
main()
go呼叫c動態庫
**如下。
@func.h
#ifndef _fun_h_
#define _fun_h_
void
print_something()
;#endif
@func.c
#include
void
print_something()
將c**編譯生成動態庫,由go**通過標頭檔案進行呼叫。
gcc -fpic -shared fun.c -o libfun.so
package main
/*#cgo cflags: -i.
#cgo ldflags: -l. -lfun
#include "fun.h"
*/import
"c"func
main()
其中有一點需要注意,cgo是不可以直接呼叫c++的**的。所以如果需要呼叫,必須在c的層面上進行一次封裝,go調c,c調c++。
go和c之間的型別轉換
c中擁有的型別都可以以c.type的形式提供給go進行傳參時的轉換,比如。
char --> c.char --> byte
signed char --> c.schar --> int8
unsigned char --> c.uchar --> uint8
short int --> c.short --> int16
short unsigned int --> c.ushort --> uint16
int --> c.int --> int
unsigned int --> c.uint --> uint32
long int --> c.long --> int32 or int64
long unsigned int --> c.ulong --> uint32 or uint64
long long int --> c.longlong --> int64
long long unsigned int --> c.ulonglong --> uint64
float --> c.float --> float32
double --> c.double --> float64
wchar_t --> c.wchar_t -->
void * -> unsafe.pointer
上述是一些基本型別的轉換,如果需要傳遞指標型別,需要先進行unsafe.pointer的轉化,再進行強轉。
將byte作為char*傳遞
#將[
]byte作為char*傳遞
str :=
byte
("hello world"
)tmp :=
(*c.char)
(unsafe.
pointer
(&str[0]
))
由於slice自身是乙個結構體,我們需要傳遞的只是其中的data部分,所以需要取資料部分的首位址。這裡還有個地方需要注意,由於我們傳遞的是資料段的首位址,所以這段資料並沒有結束符,所以需要我們手動新增結束符,或者同時傳遞slice的真實長度,避免記憶體越界。
傳遞函式指標
package main
/*#cgo cflags: -i.
#cgo ldflags: -l.
typedef void (*callback)();
static void do_cb(callback fun)
void cb();
*/import
"c"import
"fmt"
//export cb
funccb(
)func
main()
這裡的方式比較特別,先在c**中宣告函式型別,再export到go**中進行定義,個人推測可能是由於編譯出的函式名不同,導致不能直接進行強制轉換。注意要在export的函式名上進行注釋說明,不然編譯器會認定兩個cb是不同的函式。
上述方法只是總結了作者在專案中使用的一些方法。如果還有其他需求,可以嘗試在原始碼中($gopath/cmd/cgo)找找方法。
c 公共類直接調方法
c 公共類直接調方法 c codeusing system using system.collections.generic using system.data using system.data.oracleclient using system.web.ui.webcontrols namesp...
C 泛型類和集合類的方法
fcl中集合 泛型類 列表 arraylist 使用大小可按需動態增加的陣列實現 ilist 介面。bitarray 管理位值的壓縮陣列,該值表示為布林值,其中 true 表示位是開啟的 1 false 表示位是關閉的 0 stack 表示物件的簡單的後進先出非泛型集合。queue 表示物件的先進先...
C 中的abstract 類和方法
c 中的abstract類不能被例項化,他只提供其他類的繼承的介面 using system abstract class myabs class myclass myabs class myclient 乙個抽象類可以包含abstract方法,也可包含例項化方法,但繼承類 非抽象 必須實現abst...