快速上手 CGO,掌握在 Go 里写 C!

article/2025/8/30 1:28:58

大家好,最近因为各种奇怪的原因,接触到了 Go 特色之一 CGO。这方面的相关内容也相对少一些,给大家抛砖引玉,有经验的大佬欢迎补充。

f753b4bec073f8144b4050419c5eb7ea.png
图片来源于 marlin

毕竟很多跨语言调用,还是会依赖 CGO 这个特性。希望大家在真正要用时有个前置知识垫肚子。

CGO 是什么

CGO 就是 C 和 Go,两个编程语言。指的是能够创建调用 C 代码的 Go 包。对照着 Go 代码中的 “C”:

package mainimport "C"func main() {}

一旦程序中出现 import "C",则意味着开启 CGO 特性。在进行 go build 等阶段时,将会调用 C 编译器(通常是 gcc 或 clang)。

CGO 对应的环境变量是 CGO_ENABLED,设置为 1 则开启 CGO,为 0 则关闭 CGO。

编译命令如下:

CGO_ENABLED=0 go build -o hellojy main.go

当然,对于默认值。该环境变量值为 1,C 编译器也是使用 gcc。我们可以通过 go env 看到:

003f6194f1d29bf86a9572e3e9457a59.png

一旦关闭就会影响 CGO 编译。需要特别留意,交叉编译时会默认关闭 CGO。

CGO 快速上手

最小 Demo

先来一个 CGO 的 Go 例子:

package main//#include <stdio.h>
import "C"func main() {s := C.CString("hello world.")C.puts(s)
}

运行 go run main.go,输出结果:

hello world.

声明 C 注解

如果你没有了解过 CGO,看到上面的例子,可能会有好几个疑问。

首先是 include:

//#include <stdio.h>
import "C"

import "C" 我们懂,是导入 C 的伪包。前面的注解是什么?

无论是:

//#include <stdio.h>

又或是:

/*
#include <stdio.h>
#include <stdlib.h>
*/

实际上这是导入 C 前的注解,注解内容可以包含任何 C 代码,例如:函数、变量的声明定义、库引用等。(该注解要紧挨导入语句)

回到 Demo 本身,如果我们去掉 //#include <stdio.h>,再运行会出现如下报错:

# command-line-arguments
./main.go:7:2: could not determine kind of name for C.puts

去掉后,语句 C.puts(s) 将无法运行。

实际上 stdio.h 的全称是:standard input output.header(标准输入输出头文件)。该文件大都是些输入输出函数的声明,引用了这库,就能使用 C 的 puts 方法。

其他同理,你在注解中声明、定义的东西,均可以在 Go 代码中通过 C 这个伪包来引用和调用。

其次像是 CString 方法,属于在 Go 和 C 类型之间需要复制数据的特殊函数,伪包 C 有进行预定义。

例如:

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 类型对照

Go 官方有提供一份基础类型的对照表,大家可以参照来使用和理解。

如下:

C 语言类型CGO 类型Go语言类型
charC.charbyte
singed charC.scharint8
unsigned charC.ucharuint8
shortC.shortint16
unsigned shortC.ushortuint16
intC.intint32
unsigned intC.uintuint32
longC.longint32
unsigned longC.ulonguint32
long long intC.longlongint64
unsigned long long intC.ulonglonguint64
floatC.floatfloat32
doubleC.doublefloat64
size_tC.size_tuint

注意事项

使用 CGO,除了会带来一定的性能损耗外。需要特别注意的是:内存泄露。因为 Go 是带垃圾回收机制的编程语言,而使用了 C 后,需要手动的管理内存。

还是这个 Demo:

package main//#include <stdio.h>
import "C"func main() {s := C.CString("hello world.")C.puts(s)
}

如果这是一个常驻进程,也没有任何释放动作。用 C.CString 方法所申请的变量 s 就会泄露。

因此与 “C” 相关的变量创建,需要进行手动的内存管理。正确的代码如下:

/*
#include <stdio.h>
#include <stdlib.h>
*/
import "C"
import ("unsafe"
)func main() {b := C.CString("hello world.")C.puts(b)C.free(unsafe.Pointer(b))
}

需要调用 C.free 方法进行主动的内存释放。如果该程序自然结束,也会自动回收。

总结

在今天这篇文章中,我们介绍了 Go 语言中 CGO 的基础知识和快速入门。整体上,只要适应了写法,CGO 的用法就不算太麻烦。

需要特别注意手动内存管理、性能损耗等多方面的制约。后续我们也会继续深入 CGO 方面的内容。

- END -

扫码关注公众号「网管叨bi叨」

给网管个星标,第一时间吸我的知识 👆

网管整理了一本《Go 开发参考书》收集了70多条开发实践。去公众号回复【gocookbook】领取!还有一本《k8s 入门实践》讲解了常用软件在K8s上的部署过程,公众号回复【k8s】即可领取!

觉得有用就点个在看  👇👇👇


http://chatgpt.dhexx.cn/article/NKw1FTh7.shtml

相关文章

DevOps学习心得总结

流程步骤&#xff1a; 1、PLAN 制定计划 &#xff08;牢记交付给用户的目标&#xff09; 2、CODE 开始编码 &#xff08;使用相同的代码&#xff0c;不同版本的代码存储到仓库中&#xff0c;借助Git等工具在需要时合并【版本控制】&#xff09; 3、BUILD 构建阶段…

DevOps工具链

DevOps是敏捷研发中持续构建&#xff08;Continuous Build&#xff0c;CB&#xff09;、持续集成&#xff08;Continuous Integration&#xff0c;CI&#xff09;、持续交付&#xff08;Continuous Delivery&#xff0c;CD&#xff09;的自然延伸&#xff0c;从研发周期向右扩展…

DevOps及DevOps常用的工具介绍

目录 1. 什么是 DevOps2. DevOps 概念的起源2.1. 单体架构 瀑布模式2.2. 分布式架构 敏捷开发模式2.2.1. 多人协同开发问题2.2.2. 多机器问题2.2.3. 开发和运维角色的天生对立问题 2.3. 微服务架构 DevOps 3. DevOps 到底是什么4. DevOps 常用的工具4.1. Jenkins4.2. Kubern…

DevOps 简史

【注】本文节译自&#xff1a;https://www.bmc.com/blogs/devops-history/   IT 行业的当前状态受技术进步在整个历史中所产生的连锁效应所影响。不时出现的新技术极大地改变了世界运转的方式。最近&#xff0c;技术进步似乎开始以惊人的速度出现。自从互联网出现以来&#…

DevOps 学习

目录 一、概述 1、CI/CD简介 二、Git简介 三、Jenkins简介 一、概述 DevOps是Development和Operations的组合&#xff0c;也就是开发和运维的简写。 DevOps集文化理念、实践与工具于一身&#xff0c;可以提高组织高速交付应用程序和服务的能力&#xff0c;与使用传统软件…

DevOps实践

数字化时代&#xff0c;技术的交付速度和质量&#xff0c;直接关系业务的发展和创新。IT 技术交付和运行的效率&#xff0c;成为决定数字化转型成败的关键&#xff0c;而 DevOps 要解决的问题正在于此&#xff0c;DevOps 成为数字化转型的重要一环。 能力构建 随着云原生技术的…

DevOps的前世今生

导语 DevOps诞生已经13年了&#xff0c;你理解他吗&#xff1f; 为什么相伴了13年&#xff0c;你仍然对他不甚了了呢&#xff1f; 你真的以为DevOps是一个筐&#xff0c;什么东西都可以往里装吗&#xff1f; 你以为DevOps落地就是找一个JIRA&#xff08;敏捷管理工具&#…

Learning DevOps

什么是 DevOps DevOps&#xff08;Development & Operations&#xff09;/de’vps/ 是一组过程、方法与系统的统称&#xff0c;用于促进开发 (Dev)、技术运营 (Ops)和质量保障&#xff08;QA&#xff09;部门之间的沟通、协作与整合。 DevOps 的开发流程 软件从零开始到…

DevOps思想

什么是DevOps&#xff1f; DevOps是一种思想或方法论&#xff0c;它涵盖了开发、测试、运维的整个过程&#xff01;DevOps强调开发、测试、运维、质检(QA)部门之间的有效沟通与协作。强调通过自动化的方法管理软件变更、软件集成。使软件从构建到测试、发布更加快捷、可靠&…

DevOps的发展史

公众号关注 「奇妙的 Linux 世界」 设为「星标」&#xff0c;每天带你玩转 Linux &#xff01; — 1 — 可操作的概述 多亏了云计算和开源&#xff0c;软件开发的速度从几年缩短到几个月。每家公司都在向一个软件公司转变。DevOps 已迅速成为公司大规模开发和部署软件的最有效方…

DevOps——简析

节选自百度等资料 知乎解析连接 一、DevOps的目的 只有一个&#xff1a;提高开发到运维发布版本的效率。 1.初级应用&#xff1a;开发运维一体化 2.最高阶的应用&#xff1a;端到端的概念。 DevOps 的三大支柱之中&#xff0c;即人&#xff08;People&#xff09;、流程&…

DevOps推广实践总结

中大型团队在敏捷DevOps转型过程中常见的实践总结 目录 1、聘用外部DevOps顾问 2、建立DevOps共识 3、采用“DevOps改进”而非“DevOps转型” 4、构建“比学赶超”的组织氛围 5、规范化DevOps实践 1、聘用外部DevOps顾问 小型团队可以不用聘用昂贵的外部教练&#xff0c;因…

DevOps

DevOps 一、DevOps的由来和概念1. 由来2. DevOps概念解析&#xff08;1&#xff09;来自不同渠道和来源的定义&#xff1a;&#xff08;2&#xff09;其他摘录 二、DevOps 工作流程1. DevOps的好处与价值2. DevOps能力环 三、devops流程工具四、DevOps发展现状哪些互联网公司采…

Devops的概念

1、什么是DevOps&#xff1f; 答&#xff1a;DevOps是产品开发过程中开发&#xff08;Dev&#xff09;和运营&#xff08;Ops&#xff09;团队之间的灰色区域。DevOps是一种在产品开发周期中强调沟通&#xff0c;集成和协作的文化。因此&#xff0c;它消除了软件开发团队和运营…

DevOps—基本概念

DevOps—基本概念 1. DevOps2. CI/CD 1. DevOps 维基百科定义&#xff1a; DevOps是一组过程、方法与系统的统称&#xff0c;用于促进 开发、技术运营 和 质量保障&#xff08;QA&#xff09; 部门之间的沟通、协作与整合。我理解DevOps是一种软件管理思维模式。 为什么会有D…

DevOps简介

一、DevOps定义&#xff1a;Development和Operations的组合&#xff0c;突出重视软件开发人员与运维人员的沟通合作&#xff0c;通过自动化流程使得软件构建、测试、发布更加快捷、频繁和可靠。 它是一个完整的面向IT运维的工作流&#xff0c;以 IT 自动化以及持续集成&#xf…

什么是 DevOps?看这一篇就够了!

文章目录 一、前因二、记忆三、他们说……3.1、Atlassian 回答“什么是 DevOps&#xff1f;”3.2、微软回答“什么是 DevOps&#xff1f;”3.3、AWS 回答“什么是 DevOps&#xff1f;” 四、DevOps 文化4.1、什么是文化&#xff1f;4.2、什么是 DevOps 文化&#xff1f;4.3、领…

Devops基本概念和原理

一、什么是DevOps 1、 DevOps概述 DevOps&#xff0c;即Development and Operations&#xff0c;是一组过程、方法与系统的统称&#xff0c;用于促进软件开发、运维和质量保障部门之间的沟通、协作与整合。DevOps的出现是由于软件行业日益清晰的认识到&#xff1a;为了按时交…

DevOps概念及搭建全过程(Jenkins、Harbor、SonarQube、K8s)

DevOps入门及过程搭建 在如今互联网的格局下&#xff0c;抢占市场变得尤为重要&#xff0c;因此敏捷开发越来越被大家所推崇。于是&#xff0c;慢慢的有了DevOps这个概念&#xff0c;大致意思是开发-运维一体化。 1 DevOps概念 1.1 基本概念 可以看到上图是一个无穷大的一个符…

Hzero数据库初始化

一&#xff1a;获取种子数据: git地址&#xff1a;https://gitlab.flytiger.net/huying-hzero/hzero-resource.git 二&#xff1a;配置数据库信息 打开hzero-resource项目&#xff0c;编辑application.yml配置文件&#xff0c;修改对应的数据库连接信息 三&#xff1a;初始化…