前言:
在前面多篇 Go 系列文章中,我们了解到,Go 语言脱胎于 C 语言,这就意味着在某些更底层的细节中,我们可以使用 C 语言实现,然后通过 Go 来调用相关的 C 代码。其实这一特点,在 Java 的 JVM、Python 的解释器也是通过底层是直接调用 C 实现的。
而本篇文章就来学习一下,如何在 Go 语言中运行 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// 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 代码单独在一个文件。
二、Go 直接调用 C 文件
那么,如果已经写好一个封装好的 C 文件代码,Go 语言该如何调用呢?
此时我们需要直接写好 C 代码,因为 Go 代码是无法对 C 代码文件进行重写或者修改的。
写好 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
编写 C 文件
然后编写 hello.c 文件,如下:
#include "hello.h" #includeint 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 语言接收的信息: %s\n", message); } int add(int a, int b) { return a + b; }
写好 Go 代码
最后编写我们的 main.go 语言:
我们需要在 CFLAGS 参数中填入我们的 GOPath 路径,#cgo CFLAGS: -I /Users/yuzhou_1su/go/src/CinGo
。然后在 LSFLAGS 中填入我们的 C 编译后的本地链接文件:#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// #include 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 代码 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?