日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

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

新聞中心

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

大家好,我是煎魚。

成都創(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)榭蛻舫兄Z穩(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ì)少一些,給大家拋磚引玉。

圖片來源于 marlin

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

CGO 是什么

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

package main

import "C"

func main() {}

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

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

編譯命令如下:

CGO_ENABLED=0 go build -o hellojy main.go

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

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

CGO 快速上手

最小 Demo

先來一個(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 注解

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

首先是 include:

//#include 
import "C"

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

無論是:

//#include 

又或是:

/*
#include 
#include 
*/

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

回到 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

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

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

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

其次像是 CString 方法,屬于在 Go 和 C 類型之間需要復(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 類型對(duì)照

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

如下:

C 語言類型

CGO 類型

Go語言類型

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ì)帶來一定的性能損耗外。需要特別注意的是:內(nèi)存泄露。因?yàn)?Go 是帶垃圾回收機(jī)制的編程語言,而使用了 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)程,也沒有任何釋放動(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 語言中 CGO 的基礎(chǔ)知識(shí)和快速入門。整體上,只要適應(yīng)了寫法,CGO 的用法就不算太麻煩。

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


文章標(biāo)題:快速上手GoCGO,掌握在Go里寫C!
文章來源:http://www.5511xx.com/article/cojopso.html