最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語(yǔ)言中CGO的使用實(shí)踐

 更新時(shí)間:2021年09月23日 11:44:35   作者:mrsonko  
本文主要介紹了Go語(yǔ)言中CGO的使用實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

       部門產(chǎn)品業(yè)務(wù)功能采用Golang開發(fā),但是有些功能是用c寫的,比如說(shuō)net-snmp,bfd協(xié)議等等,像這些如果使用GO語(yǔ)言重編的話,既有實(shí)現(xiàn)的復(fù)雜度也需要相當(dāng)長(zhǎng)的時(shí)間,好在GO語(yǔ)言提供了CGO機(jī)制,使得能夠在go代碼中直接調(diào)用C的庫(kù)函數(shù),大大提高了效率,減少了重復(fù)開發(fā)工作,此外還支持在C語(yǔ)言中調(diào)用GO函數(shù),這一點(diǎn)還是蠻強(qiáng)大的。

1. Go語(yǔ)言調(diào)用C函數(shù)例子:

package main
 
//
// 引用的C頭文件需要在注釋中聲明,緊接著注釋需要有import "C",且這一行和注釋之間不能有空格
//
 
/*
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void myprint(char* s) {
	printf("%s\n", s);
}
*/
import "C"
 
 
import (
	"fmt"
	"unsafe"
)
 
func main() {
	//使用C.CString創(chuàng)建的字符串需要手動(dòng)釋放。
	cs := C.CString("Hello World\n")
	C.myprint(cs)
	C.free(unsafe.Pointer(cs))
	fmt.Println("call C.sleep for 3s")
	C.sleep(3)
	return
}

運(yùn)行:

2. Go語(yǔ)言調(diào)用C庫(kù)函數(shù):

hello.c

#include <stdio.h>
void hello()
{
    printf("hello world\n"); 
}

hello.h

#ifndef HELLO_H
#define HELLO_H
 
void hello(void);
#endif

編譯:

gcc -c hello.c
ar -cru libhello.a hello.o
package main
 
//使用#cgo定義庫(kù)路徑
 
 
/*
#cgo CFLAGS: -I .
#cgo LDFLAGS: -L . -lhello
#include "hello.h"
*/
import "C"
 
func main() {
	C.hello()
}

運(yùn)行:

3. Go語(yǔ)言導(dǎo)出函數(shù)給C語(yǔ)言使用:

main.go

package main
 
//
//#include <stdio.h>
//int add(int a, int b);
//
import "C"
 
import (
	"fmt"
)
 
//當(dāng)使用export的時(shí)候,在同一個(gè)文件中就不能再定義其它的c函數(shù)了,不然會(huì)報(bào)錯(cuò)。
//使用export導(dǎo)出函數(shù)給c語(yǔ)言調(diào)用。
 
//export GoAdd
func GoAdd(a, b int) int {
	return a + b
}
 
func main() {
	a := C.add(1, 2)
	fmt.Printf("C.add(1,2) return %d\n", a)
}

cfunc.go

package main
 
//
//int GoAdd(int a, int b); 
//
//int add(int a, int b)
//{
//	  return GoAdd(a,b);
//}
//
import "C"

運(yùn)行:

4. Go語(yǔ)言導(dǎo)出函數(shù)指針給c語(yǔ)言使用:

還有一種使用方式,這種是我使用比較多的。就是傳遞函數(shù)指針,因?yàn)镚O函數(shù)無(wú)法取址,因此需要寫個(gè)中間函數(shù)做個(gè)轉(zhuǎn)換操作,例子如下:

clibrary.c

#include <stdio.h>
 
#include "clibrary.h"
 
//參數(shù)是函數(shù)指針
void some_c_func(callback_fcn callback)
{
	int arg = 2;
	printf("C.some_c_func(): calling callback with arg = %d\n", arg);
	int response = callback(2);
	printf("C.some_c_func(): callback responded with %d\n", response);
}

 clibrary.h

#ifndef CLIBRARY_H
#define CLIBRARY_H
//定義函數(shù)指針
typedef int (*callback_fcn)(int);
void some_c_func(callback_fcn);
#endif

Go code:

package main
 
/*
#cgo CFLAGS: -I .
#cgo LDFLAGS: -L . -lclibrary
#include "clibrary.h"
int callOnMeGo_cgo(int in); // 聲明
*/
import "C"
 
import (
	"fmt"
	"unsafe"
)
 
//export callOnMeGo
func callOnMeGo(in int) int {
	return in + 1
}
 
func main() {
	fmt.Printf("Go.main(): calling C function with callback to us\n")
 
    //使用unsafe.Pointer轉(zhuǎn)換
	C.some_c_func((C.callback_fcn)(unsafe.Pointer(C.callOnMeGo_cgo)))
}

中間函數(shù):

package main
 
/*
 
#include <stdio.h>
int callOnMeGo(int);
 
// The gateway function
int callOnMeGo_cgo(int in)
{
	printf("C.callOnMeGo_cgo(): called with arg = %d\n", in);
    //調(diào)用GO函數(shù)
	return callOnMeGo(in);
}
*/
import "C"

運(yùn)行:

開發(fā)注意事項(xiàng):

1. 在注釋和import”C”之間不能有空行

2. 使用C.CString函數(shù)轉(zhuǎn)換GoString為CString時(shí)要手動(dòng)釋放該字符串。

3. CGO不支持使用變參的函數(shù),例如printf,如果要使用的話,可以寫個(gè)包裹函數(shù)m'yprintf,使用傳參的方式調(diào)用。

4. Go支持使用//export導(dǎo)出函數(shù)給C使用,但是有一點(diǎn)需要注意就是不能在export導(dǎo)出的同一個(gè)文件里定義c函數(shù),不然會(huì)出現(xiàn)

multiple definition of "xxx"編譯錯(cuò)誤,如果函數(shù)非常tiny的話,還有一個(gè)方法是使用static inline 來(lái)聲明該函數(shù),如下:

package gocallback
 
import (
	"fmt"
	"sync"
)
 
/*
extern void go_callback_int(int foo, int p1);
// normally you will have to define function or variables
// in another separate C file to avoid the multiple definition
// errors, however, using "static inline" is a nice workaround
// for simple functions like this one.
static inline void CallMyFunction(int foo) {
	go_callback_int(foo, 5);
}
*/
import "C"
 

參考資料:

1. https://github.com/golang/go/wiki/cgo

到此這篇關(guān)于Go語(yǔ)言中CGO的使用實(shí)踐的文章就介紹到這了,更多相關(guān)Go語(yǔ)言使用CGO內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • GO中對(duì)map排序的實(shí)現(xiàn)

    GO中對(duì)map排序的實(shí)現(xiàn)

    本文主要介紹了GO中對(duì)map排序的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Go語(yǔ)言實(shí)現(xiàn)支付寶支付與退款詳解

    Go語(yǔ)言實(shí)現(xiàn)支付寶支付與退款詳解

    本文詳細(xì)介紹使用Go語(yǔ)言對(duì)接支付寶支付與退款功能的步驟和注意事項(xiàng),包括PC端、WAP端和Android端支付實(shí)現(xiàn),以及退款功能的代碼實(shí)現(xiàn),介紹了GoPay庫(kù)的使用,幫助開發(fā)者快速集成支付寶支付到應(yīng)用中
    2024-10-10
  • Golang實(shí)現(xiàn)yaml配置文件的解析

    Golang實(shí)現(xiàn)yaml配置文件的解析

    這篇文章主要介紹了Golang實(shí)現(xiàn)yaml配置文件的解析,文中通過(guò)圖文結(jié)合的方式講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-12-12
  • Golang 類型轉(zhuǎn)換的實(shí)現(xiàn)(斷言、強(qiáng)制、顯式類型)

    Golang 類型轉(zhuǎn)換的實(shí)現(xiàn)(斷言、強(qiáng)制、顯式類型)

    將一個(gè)值從一種類型轉(zhuǎn)換到另一種類型,便發(fā)生了類型轉(zhuǎn)換,在go可以分為斷言、強(qiáng)制、顯式類型轉(zhuǎn)換,本文就詳細(xì)的介紹一下這就幾種轉(zhuǎn)換方式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • Go|使用Options模式和建造者模式創(chuàng)建對(duì)象實(shí)戰(zhàn)

    Go|使用Options模式和建造者模式創(chuàng)建對(duì)象實(shí)戰(zhàn)

    這篇文章主要介紹了Go使用Options模式和建造者模式創(chuàng)建對(duì)象實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • grpc-go如何通過(guò)context傳遞額外數(shù)據(jù)

    grpc-go如何通過(guò)context傳遞額外數(shù)據(jù)

    metadata是grpc內(nèi)置的,用RPC服務(wù)傳遞http頭數(shù)據(jù),分in和out兩種,對(duì)應(yīng)的key都為一個(gè)空struct,這篇文章主要介紹了grpc-go通過(guò)context傳遞額外數(shù)據(jù),需要的朋友可以參考下
    2024-02-02
  • Golang微服務(wù)框架Kratos實(shí)現(xiàn)分布式任務(wù)隊(duì)列Asynq的方法詳解

    Golang微服務(wù)框架Kratos實(shí)現(xiàn)分布式任務(wù)隊(duì)列Asynq的方法詳解

    任務(wù)隊(duì)列(Task Queue) 一般用于跨線程或跨計(jì)算機(jī)分配工作的一種機(jī)制,在Golang語(yǔ)言里面,我們有像Asynq和Machinery這樣的類似于Celery的分布式任務(wù)隊(duì)列,本文就給大家詳細(xì)介紹一下Golang微服務(wù)框架Kratos實(shí)現(xiàn)分布式任務(wù)隊(duì)列Asynq的方法,需要的朋友可以參考下
    2023-09-09
  • Go和Java算法詳析之分?jǐn)?shù)到小數(shù)

    Go和Java算法詳析之分?jǐn)?shù)到小數(shù)

    這篇文章主要給大家介紹了關(guān)于Go和Java算法詳析之分?jǐn)?shù)到小數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Ubuntu下安裝Go語(yǔ)言開發(fā)環(huán)境及編輯器的相關(guān)配置

    Ubuntu下安裝Go語(yǔ)言開發(fā)環(huán)境及編輯器的相關(guān)配置

    這篇文章主要介紹了Ubuntu下安裝Go語(yǔ)言開發(fā)環(huán)境及編輯器的相關(guān)配置,編輯器方面介紹了包括Vim和Eclipse,需要的朋友可以參考下
    2016-02-02
  • OpenTelemetry-go的SDK使用方法詳解

    OpenTelemetry-go的SDK使用方法詳解

    這篇文章主要介紹了OpenTelemetry-go的SDK使用方法,OpenTelemetry幫我們實(shí)現(xiàn)了相應(yīng)語(yǔ)言的SDK,所以我們只需要進(jìn)行調(diào)用即可,本文根據(jù)官方文檔實(shí)例講解,需要的朋友可以參考下
    2022-09-09

最新評(píng)論

永顺县| 清徐县| 岳普湖县| 莱阳市| 武汉市| 上饶市| 锦屏县| 固始县| 肥西县| 彩票| 南郑县| 高台县| 府谷县| 陆川县| 桐庐县| 吉木萨尔县| 冕宁县| 江西省| 滦南县| 金堂县| 巴彦淖尔市| 阜平县| 翁源县| 任丘市| 义马市| 健康| 西平县| 玉门市| 宁国市| 雷波县| 五寨县| 婺源县| 永德县| 广西| 郎溪县| 屯昌县| 霍城县| 清徐县| 睢宁县| 汝城县| 宣汉县|