golang調C的基本方法和型別轉換

2021-10-01 09:18:31 字數 2538 閱讀 8560

本文主要記錄一些之前在專案中使用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...