日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
快速上手GoCGO,掌握在Go里寫(xiě)C!

大家好,我是煎魚(yú)。

成都創(chuàng)新互聯(lián)主打移動(dòng)網(wǎng)站、成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、網(wǎng)站改版、網(wǎng)絡(luò)推廣、網(wǎng)站維護(hù)、主機(jī)域名、等互聯(lián)網(wǎng)信息服務(wù),為各行業(yè)提供服務(wù)。在技術(shù)實(shí)力的保障下,我們?yōu)榭蛻?hù)承諾穩(wěn)定,放心的服務(wù),根據(jù)網(wǎng)站的內(nèi)容與功能再?zèng)Q定采用什么樣的設(shè)計(jì)。最后,要實(shí)現(xiàn)符合網(wǎng)站需求的內(nèi)容、功能與設(shè)計(jì),我們還會(huì)規(guī)劃穩(wěn)定安全的技術(shù)方案做保障。

最近因?yàn)楦鞣N奇怪的原因,接觸到了 Go 特色之一 CGO。這方面的相關(guān)內(nèi)容也相對(duì)少一些,給大家拋磚引玉。

圖片來(lái)源于 marlin

畢竟很多跨語(yǔ)言調(diào)用,還是會(huì)依賴(lài) CGO 這個(gè)特性。希望大家在真正要用時(shí)有個(gè)前置知識(shí)墊肚子。

CGO 是什么

CGO 就是 C 和 Go,兩個(gè)編程語(yǔ)言。指的是能夠創(chuàng)建調(diào)用 C 代碼的 Go 包。對(duì)照著 Go 代碼中的 “C”:

package main

import "C"

func main() {}

一旦程序中出現(xiàn) import "C",則意味著開(kāi)啟 CGO 特性。在進(jìn)行 go build 等階段時(shí),將會(huì)調(diào)用 C 編譯器(通常是 gcc 或 clang)。

CGO 對(duì)應(yīng)的環(huán)境變量是 CGO_ENABLED,設(shè)置為 1 則開(kāi)啟 CGO,為 0 則關(guān)閉 CGO。

編譯命令如下:

CGO_ENABLED=0 go build -o hellojy main.go

當(dāng)然,對(duì)于默認(rèn)值。該環(huán)境變量值為 1,C 編譯器也是使用 gcc。我們可以通過(guò) go env 看到:

一旦關(guān)閉就會(huì)影響 CGO 編譯。需要特別留意,交叉編譯時(shí)會(huì)默認(rèn)關(guān)閉 CGO。

CGO 快速上手

最小 Demo

先來(lái)一個(gè) CGO 的 Go 例子:

package main

//#include 
import "C"

func main() {
 s := C.CString("hello world.")
 C.puts(s)
}

運(yùn)行 go run main.go,輸出結(jié)果:

hello world.

聲明 C 注解

如果你沒(méi)有了解過(guò) CGO,看到上面的例子,可能會(huì)有好幾個(gè)疑問(wèn)。

首先是 include:

//#include 
import "C"

import "C" 我們懂,是導(dǎo)入 C 的偽包。前面的注解是什么?

無(wú)論是:

//#include 

又或是:

/*
#include 
#include 
*/

實(shí)際上這是導(dǎo)入 C 前的注解,注解內(nèi)容可以包含任何 C 代碼,例如:函數(shù)、變量的聲明定義、庫(kù)引用等。(該注解要緊挨導(dǎo)入語(yǔ)句)

回到 Demo 本身,如果我們?nèi)サ?nbsp;//#include ,再運(yùn)行會(huì)出現(xiàn)如下報(bào)錯(cuò):

# command-line-arguments
./main.go:7:2: could not determine kind of name for C.puts

去掉后,語(yǔ)句 C.puts(s) 將無(wú)法運(yùn)行。

實(shí)際上 stdio.h 的全稱(chēng)是:standard input output.header(標(biāo)準(zhǔn)輸入輸出頭文件)。該文件大都是些輸入輸出函數(shù)的聲明,引用了這庫(kù),就能使用 C 的 puts 方法。

其他同理,你在注解中聲明、定義的東西,均可以在 Go 代碼中通過(guò) C 這個(gè)偽包來(lái)引用和調(diào)用。

其次像是 CString 方法,屬于在 Go 和 C 類(lèi)型之間需要復(fù)制數(shù)據(jù)的特殊函數(shù),偽包 C 有進(jìn)行預(yù)定義。

例如:

func C.CString(string) *C.char
func C.CBytes([]byte) unsafe.Pointer
func C.GoString(*C.char) string
func C.GoStringN(*C.char, C.int) string
func C.GoBytes(unsafe.Pointer, C.int) []byte

Go 和 C 類(lèi)型對(duì)照

Go 官方有提供一份基礎(chǔ)類(lèi)型的對(duì)照表,大家可以參照來(lái)使用和理解。

如下:

C 語(yǔ)言類(lèi)型

CGO 類(lèi)型

Go語(yǔ)言類(lèi)型

char

C.char

byte

singed char

C.schar

int8

unsigned char

C.uchar

uint8

short

C.short

int16

unsigned short

C.ushort

uint16

int

C.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

注意事項(xiàng)

使用 CGO,除了會(huì)帶來(lái)一定的性能損耗外。需要特別注意的是:內(nèi)存泄露。因?yàn)?Go 是帶垃圾回收機(jī)制的編程語(yǔ)言,而使用了 C 后,需要手動(dòng)的管理內(nèi)存。

還是這個(gè) Demo:

package main

//#include 
import "C"

func main() {
 s := C.CString("hello world.")
 C.puts(s)
}

如果這是一個(gè)常駐進(jìn)程,也沒(méi)有任何釋放動(dòng)作。用 C.CString 方法所申請(qǐng)的變量 s 就會(huì)泄露。

因此與 “C” 相關(guān)的變量創(chuàng)建,需要進(jìn)行手動(dòng)的內(nèi)存管理。正確的代碼如下:

/*
#include 
#include 
*/
import "C"
import (
 "unsafe"
)

func main() {
 b := C.CString("hello world.")
 C.puts(b)
 C.free(unsafe.Pointer(b))
}

需要調(diào)用 C.free 方法進(jìn)行主動(dòng)的內(nèi)存釋放。如果該程序自然結(jié)束,也會(huì)自動(dòng)回收。

總結(jié)

在今天這篇文章中,我們介紹了 Go 語(yǔ)言中 CGO 的基礎(chǔ)知識(shí)和快速入門(mén)。整體上,只要適應(yīng)了寫(xiě)法,CGO 的用法就不算太麻煩。

需要特別注意手動(dòng)內(nèi)存管理、性能損耗等多方面的制約。后續(xù)我們也會(huì)繼續(xù)深入 CGO 方面的內(nèi)容。


網(wǎng)頁(yè)標(biāo)題:快速上手GoCGO,掌握在Go里寫(xiě)C!
當(dāng)前地址:http://www.dlmjj.cn/article/cojopso.html