脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - Go 语言中运行 C程序 代码

Go 语言中运行 C程序 代码

2022-09-08 11:26宇宙之一粟 Golang

这篇文章主要介绍了Go 语言中运行 C程序代码,通过直接在 Go 代码中写入 C 程序运行,下面操作过程需要的小伙伴可以参考一下

前言:

在前面多篇 Go 系列文章中,我们了解到,Go 语言脱胎于 C 语言,这就意味着在某些更底层的细节中,我们可以使用 C 语言实现,然后通过 Go 来调用相关的 C 代码。其实这一特点,在 Java 的 JVM、Python 的解释器也是通过底层是直接调用 C 实现的。

而本篇文章就来学习一下,如何在 Go 语言中运行 C 程序。

一、直接在 Go 代码中写入 C 程序

Go 语言通过 cgo 工具来识别代码中的 C 语言,我们可以通过命令 ​​go env​​ 来查看是否 cgo 工具是否开启。

Go 语言中运行 C程序 代码

​​CGO_ENABLED=1​​ 表示 cgo 工具可用,当设置为 0 时,表示工具不可用。

然后我可以新建一个​​CinGo.go​​​ 的程序,然后在注释中写入 c 语言的代码。然后导入 Go 提供的 c 包 ​​import "C"​​ ,Go 语言在看到导入这个包之后就知道如何去处理注释中的内容了。

这里我们在 C 代码中写入要给 ​​callC()​​ 函数,然后在 Go 语言中进行调用:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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​​ 的头文件,

代码如下:

?
1
2
3
4
5
6
7
8
9
#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​​ 文件,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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 语言接收的信息: %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​​ 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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)
 
}

​最后代码结构如下:

Go 语言中运行 C程序 代码

然后我们首先编译 c 代码:

?
1
2
3
4
5
$ gcc -c *.c      
 
$ /usr/bin/ar rs hello.a *.o
ar: creating archive hello.a
$ rm hello.o

然后再执行 Go 代码,结果如下:

?
1
2
3
$ 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 代码 内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.51cto.com/yuzhou1su/5111291

延伸 · 阅读

精彩推荐
  • GolangGolang Http 验证码示例实现

    Golang Http 验证码示例实现

    这篇文章主要介绍了Golang Http 验证码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小...

    xialeistudio4752020-09-06
  • Golanggo语言标准库fmt包的一键入门

    go语言标准库fmt包的一键入门

    这篇文章主要为大家介绍了go语言标准库fmt包的一键入门使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加...

    梦想橡皮擦8612022-08-01
  • GolangGo语言生成素数的方法

    Go语言生成素数的方法

    这篇文章主要介绍了Go语言生成素数的方法,实例分析了Go语言生成素数的技巧,需要的朋友可以参考下 ...

    依山带水3212020-04-21
  • Golang详解golang中的method

    详解golang中的method

    这篇文章主要介绍了golang中的method的相关资料,帮助大家更好的理解和使用golang,感兴趣的朋友可以了解下...

    雨燕5842021-03-24
  • Golang在Golang代码中如何自动生成版本号的方法示例

    在Golang代码中如何自动生成版本号的方法示例

    这篇文章主要给大家介绍了在Golang代码中如何自动生成版本号的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋...

    andy zhang7402020-05-07
  • Golanggolang 数组随机排序的实现

    golang 数组随机排序的实现

    本文主要介绍了golang 数组随机排序的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    董洪臣7522022-01-26
  • GolangGo语言基础闭包的原理分析示例详解

    Go语言基础闭包的原理分析示例详解

    这篇文章主要为大家介绍了Go语言基础闭包的底层原理及实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪...

    枫少文8572021-12-05
  • Golang成功安装vscode中go的相关插件(详细教程)

    成功安装vscode中go的相关插件(详细教程)

    这篇文章主要介绍了成功安装vscode中go的相关插件的详细教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以...

    Leo_wlCnBlogs3382020-07-05