C如何调用Go
在本文中,我们将学习如何将 Go 代码编译成 C 动态库,并通过 C 程序调用 Go 动态库中的函数。我们将逐步介绍如何生成 Go 动态库,如何编写 C 程序来调用 Go 函数,以及如何在 C 程序中链接 Go 生成的共享库。
1. 目标
- 将 Go 函数编译成 C 动态库(共享库)。
- 在 C 程序中加载并调用 Go 动态库中的函数。
2. 环境准备
确保你的系统已经安装了以下工具:
- Go 语言:确保安装了 Go 1.11 或更高版本。
- GCC:用于编译 C 代码并链接 Go 动态库。
3. 创建 Go 动态库
Go 提供了 -buildmode=c-shared
选项,允许我们将 Go 代码编译成 C 动态库(.so
文件)。
3.1 编写 Go 代码
首先,我们编写一个简单的 Go 代码文件,包含一个 Add
函数,用于返回两个整数的和。我们将通过 //export
注释来将 Add
函数导出给 C 程序。
go_functions.go:
// go_functions.go package main import "C" //export Add func Add(a, b int) int { return a + b }
在上面的 Go 代码中:
Add
函数通过//export Add
注释导出,表示该函数可以被 C 程序调用。Add
函数接收两个整数参数并返回它们的和。
3.2 编译 Go 动态库
我们使用 go build -buildmode=c-shared
命令将 Go 代码编译为 C 动态库。该命令会生成 .so
文件(共享库文件)和 .h
头文件,供 C 程序使用。
$ go build -o libgo_functions.so -buildmode=c-shared go_functions.go
这条命令会生成两个文件:
libgo_functions.so
:Go 动态库文件,供 C 程序调用。libgo_functions.h
:Go 动态库的 C 头文件,包含函数声明。
4. 编写 C 程序调用 Go 动态库
现在,我们编写一个 C 程序,使用 #include
指令包含 Go 动态库的头文件,并调用其中的 Add
函数。
main.c:
#include <stdio.h> #include "libgo_functions.h" // 引入 Go 生成的头文件 int main() { // 调用 Go 动态库中的 Add 函数 int result = Add(2, 3); // 打印返回值 printf("Result of Add: %d\n", result); return 0; }
在这个 C 程序中:
- 我们使用
#include "libgo_functions.h"
来引入 Go 生成的头文件。 - 然后,调用 Go 动态库中的
Add
函数,并输出结果。
5. 编译并链接 C 程序
我们需要编译 C 程序并链接 Go 生成的共享库。使用 GCC 编译器时,需要指定 Go 共享库所在的路径,并通过 -L
选项告诉 GCC 去哪里查找库文件,使用 -l
选项指定库的名称。
编译命令如下:
$ gcc main.c -o main -L. -lgo_functions -pthread -ldl -Wl,-rpath=.
命令说明:
-L.
:指定共享库的目录(.
表示当前目录),以便 GCC 找到libgo_functions.so
。-lgo_functions
:指定链接的库名。Go 动态库的文件名为libgo_functions.so
,因此我们在命令中使用-lgo_functions
(去掉前缀lib
和扩展名.so
)。-pthread
:启用多线程支持,C 程序和 Go 程序共享同一线程池时需要此选项。-ldl
:动态加载库,需要链接dl
库来处理动态库加载。-Wl,-rpath
,将共享库搜索路径嵌入到可执行文件中。这意味着程序在运行时会自动去指定的目录查找共享库,而不需要设置 LD_LIBRARY_PATH 环境变量。
6. 运行 C 程序
完成编译后,运行 C 程序以调用 Go 动态库:
$ ./main # 执行 C 程序后,输出将会显示 Go 中 `Add` 函数的返回结果: Result of Add: 5
7. 注意事项
- 在 Go 中使用
//export
注释导出函数,以便 C 程序能够调用它们。 - 在 Go 动态库编译时,不需要定义
main()
函数,因为生成的库文件不需要主函数来启动。 - 确保使用适当的选项(如
-pthread
和-ldl
)来正确处理线程和动态库加载。

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
腾讯云开发者社区:孟斯特
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
2020-12-09 根据TxID获取上链数据