<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前言:
在前面多篇 Go 系列文章中,我們瞭解到,Go 語言脫胎於 C 語言,這就意味著在某些更底層的細節中,我們可以使用 C 語言實現,然後通過 Go 來呼叫相關的 C 程式碼。其實這一特點,在 Java 的 JVM、Python 的直譯器也是通過底層是直接呼叫 C 實現的。
而本篇文章就來學習一下,如何在 Go 語言中執行 C 程式。
Go 語言通過 cgo 工具來識別程式碼中的 C 語言,我們可以通過命令 go env 來檢視是否 cgo 工具是否開啟。
CGO_ENABLED=1
表示 cgo 工具可用,當設定為 0 時,表示工具不可用。
然後我可以新建一個CinGo.go
的程式,然後在註釋中寫入 c 語言的程式碼。然後匯入 Go 提供的 c 包 import "C" ,Go 語言在看到匯入這個包之後就知道如何去處理註釋中的內容了。
這裡我們在 C 程式碼中寫入要給 callC() 函數,然後在 Go 語言中進行呼叫:
package main // #include <stdio.h> // void callC() { // printf("Hello World from C!n"); // } import "C" import "fmt" func main() { fmt.Println("讓我們學習 Go 語句呼叫 C 程式") C.callC() fmt.Println("呼叫 C 程式結束") }
執行結果:
$ go run CinGo.go
讓我們學習 Go 語句呼叫 C 程式
Hello World from C!;'/;'
呼叫 C 程式結束
但是,這種方式的 C 程式碼和 Go 語言程式碼在同一個檔案中,所以大家能明顯發現這種方式的程式碼耦合度太高,僅僅適用於專案簡單單一的情形。
一個更合理的方式應該是 C 程式碼單獨在一個檔案。
那麼,如果已經寫好一個封裝好的 C 檔案程式碼,Go 語言該如何呼叫呢?
此時我們需要直接寫好 C 程式碼,因為 Go 程式碼是無法對 C 程式碼檔案進行重寫或者修改的。
我們在本地 Go 專案中,建立一個 hello.h 的標頭檔案,
程式碼如下:
#ifndef HELLO_H #define HELLO_H int sayHello(const char *name, char *out); void printMessage(char *message); void cHello(); int add(int a, int b); #endif
然後編寫 hello.c 檔案,如下:
#include "hello.h" #include <stdio.h> int sayHello(const char *name, char *out) { int n; n = sprintf(out, "Hello, My name is %s!", name); return n; } void cHello() { printf("Hello from C!n"); } void printMessage(char* message) { printf("從 Go 語言接收的資訊: %sn", message); } int add(int a, int b) { return a + b; }
最後編寫我們的 main.go 語言:
#cgo CFLAGS: -I /Users/yuzhou_1su/go/src/CinGo
。#cgo LDFLAGS: /Users/yuzhou_1su/go/src/CinGo/hello.a
package main // #cgo CFLAGS: -I /Users/yuzhou_1su/go/src/CinGo // #cgo LDFLAGS: /Users/yuzhou_1su/go/src/CinGo/hello.a // #include <stdlib.h> // #include <hello.h> import "C" import ( "fmt" "unsafe" ) func main() { C.cHello() a := C.int(1024) b := C.int(2022) result := C.add(a, b) fmt.Println("Reuslt is:", result) goMessage := C.CString("This is Go") defer C.free(unsafe.Pointer(goMessage)) C.printMessage(goMessage) }
最後程式碼結構如下:
然後我們首先編譯 c 程式碼:
$ gcc -c *.c $ /usr/bin/ar rs hello.a *.o ar: creating archive hello.a $ rm hello.o
然後再執行 Go 程式碼,結果如下:
$ go run main.go Hello from C! Reuslt is: 3046
從 Go 語言接收的資訊: This is Go
總結:
在編寫上述的小案例過程你中的,都出現了了很多小問題,比如 C 程式碼和 import "c" 語句之間不能有空格。經常會出現找不到 C 函數等等問題。
總得來說,日常 Go 開發還是不需要此類高階用法,也就是說其實我們平常程式設計過程中不太需要 cgo,大多數情況下還是儘量用 Go 語言自己實現。如果確實需要使用 C 語言,還是得多去了解 cgo 的檔案,以防出錯。
到此這篇關於Go 語言中執行 C程式 程式碼 的文章就介紹到這了,更多相關Go中執行 C 程式碼 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45