Go入门指南-3.9与其它语言进行交互

ops/2024/10/24 16:21:13/

3.9.1 与 C 进行交互

工具 cgo 提供了对 FFI(外部函数接口)的支持,能够使用 Go 代码安全地调用 C 语言库,你可以访问 cgo 文档主页:http://golang.org/cmd/cgo。cgo 会替代 Go 编译器来产生可以组合在同一个包中的 Go 和 C 代码。在实际开发中一般使用 cgo 创建单独的 C 代码包。

如果你想要在你的 Go 程序中使用 cgo,则必须在单独的一行使用 import "C" 来导入,一般来说你可能还需要 import "unsafe"

然后,你可以在 import "C" 之前使用注释(单行或多行注释均可)的形式导入 C 语言库(甚至有效的 C 语言代码),它们之间没有空行,例如:

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

名称 “C” 并不属于标准库的一部分,这只是 cgo 集成的一个特殊名称用于引用 C 的命名空间。在这个命名空间里所包含的 C 类型都可以被使用,例如 C.uintC.long 等等,还有 libc 中的函数 C.random() 等也可以被调用。

当你想要使用某个类型作为 C 中函数的参数时,必须将其转换为 C 中的类型,反之亦然,例如:

var i int
C.uint(i) 		// 从 Go 中的 int 转换为 C 中的无符号 int
int(C.random()) // 从 C 中 random() 函数返回的 long 转换为 Go 中的 int

下面的 2 个 Go 函数 Random()Seed() 分别调用了 C 中的 C.random()C.srandom()

示例 3.2 c1.go

package rand// #include <stdlib.h>
import "C"func Random() int {return int(C.random())
}func Seed(i int) {C.srandom(C.uint(i))
}

C 当中并没有明确的字符串类型,如果你想要将一个 string 类型的变量从 Go 转换到 C 时,可以使用 C.CString(s);同样,可以使用 C.GoString(cs) 从 C 转换到 Go 中的 string 类型。

Go 的内存管理机制无法管理通过 C 代码分配的内存。

开发人员需要通过手动调用 C.free 来释放变量的内存:

defer C.free(unsafe.Pointer(Cvariable))

这一行最好紧跟在使用 C 代码创建某个变量之后,这样就不会忘记释放内存了。下面的代码展示了如何使用 cgo 创建变量、使用并释放其内存:

示例 3.3 c2.go

package print// #include <stdio.h>
// #include <stdlib.h>
import "C"
import "unsafe"func Print(s string) {cs := C.CString(s)defer C.free(unsafe.Pointer(cs))C.fputs(cs, (*C.FILE)(C.stdout))
}

构建 cgo 包

你可以在使用将会在第 9.5 节讲到的 Makefile 文件(因为我们使用了一个独立的包),除了使用变量 GOFILES 之外,还需要使用变量 CGOFILES 来列出需要使用 cgo 编译的文件列表。例如,示例 3.2 中的代码就可以使用包含以下内容的 Makefile 文件来编译,你可以使用 gomake 或 make:

include $(GOROOT)/src/Make.inc
TARG=rand
CGOFILES=\
c1.go\
include $(GOROOT)/src/Make.pkg

3.9.2 与 C++ 进行交互

SWIG(简化封装器和接口生成器)支持在 Linux 系统下使用 Go 代码调用 C 或者 C++ 代码。这里有一些使用 SWIG 的注意事项:

  • 编写需要封装的库的 SWIG 接口。
  • SWIG 会产生 C 的存根函数。
  • 这些库可以使用 cgo 来调用。
  • 相关的 Go 文件也可以被自动生成。

这类接口支持方法重载、多重继承以及使用 Go 代码实现 C++ 的抽象类。

目前使用 SWIG 存在的一个问题是它无法支持所有的 C++ 库,比如说它就无法解析 TObject.h。


http://www.ppmy.cn/ops/128102.html

相关文章

ABAQUS应用11——支座弹簧

文章目录 0、背景1、ABAQUS中几类弹簧的简介2、SPRING1的性质初探 0、背景 1、ABAQUS中几类弹簧的简介 先说参考来源&#xff0c;ABAQUS2016的帮助文档里第4卷&#xff0c;32.1.1节&#xff0c;有三种弹簧&#xff08;SPRING1 、SPRING2 以及SPRINGA&#xff09;。 三种弹簧里…

项目管理新趋势!2024年,Jira与禅道你更倾向谁?

一、 项目管理软件新趋势概述 2024 年&#xff0c;项目管理软件呈现出诸多新趋势&#xff0c;这些趋势对于项目管理的重要性日益凸显。 在数字化转型方面&#xff0c;项目管理软件成为企业实现数字化转型的关键工具。越来越多的企业认识到&#xff0c;通过项目管理软件可以实…

程序员节-回顾篇

回顾&#xff1a; 时间如白驹过隙&#xff0c;转眼间&#xff0c;我们又走过了一个充满挑战与机遇的年份。回顾过去的一年&#xff0c;心中充满了感慨与收获。 一、个人成长 这一年里&#xff0c;我在各个方面都有了显著的成长。在工作上&#xff0c;我通过不断学习和实践&a…

如何在 JavaScript 项目中限制Node.js版本

前言 在现代JavaScript开发中&#xff0c;Node.js扮演了一个非常重要的角色。不同版本的Node.js可能会带来不同的特性和行为&#xff0c;因此在项目中限制Node版本是一个很关键的步骤。 本文将通过通俗易懂的方式&#xff0c;教你如何在JavaScript项目中限制Node.js的版本。 …

玩转大模型的第一步——提示词(Prompt)工程【抛砖篇】

前言 AI大模型提示词工程&#xff0c;又名 LLM prompts Project&#xff0c;指的是在使用大型语言模型&#xff08;如OpenAI的GPT系列&#xff09;时&#xff0c;用于引导模型生成特定响应的输入&#xff0c;是在使用AI大模型过程中非常重要的一个环节&#xff0c;是模型生成文…

安全见闻(1)——开阔眼界,不做井底之蛙

内容预览 ≧∀≦ゞ 安全见闻一&#xff1a;包罗万象的网络安全声明导语编程语言常用语言函数式编程数据科学和机器学习Web全栈开发移动开发嵌入式开发其他编程语言 软件程序常见软件程序类型 操作系统非实时操作系统实时操作系统 网络通讯硬件设备计算机硬件网络硬件移动设备硬…

054_python基于爬虫与文本挖掘的网络舆情监控系统

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

构建高效在线考试平台:Spring Boot与JavaWeb的融合

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理基于JavaWeb技术的在线考试系统设计与实现…