前言:
在前面多篇 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 <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 代码单独在一个文件。
二、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" #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; }
写好 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 <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 代码 内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!
需要了解更多python教程分享Go 语言中运行 C程序 代码 ,都可以关注python教程分享栏目—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/pythontutorial/1067875.html