前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >一文以蔽之——Golang调用C语言程序详解

一文以蔽之——Golang调用C语言程序详解

原创
作者头像
liuzhen007
修改2025-01-25 21:19:26
修改2025-01-25 21:19:26
10400
代码可运行
举报
文章被收录于专栏:流媒体音视频流媒体音视频
运行总次数:0
代码可运行

前言

大家都知道Golang可以调用C语言,也可以调用C++语言,网上很多文章都是混在一起介绍的,其实二者有很大的区别。今天们先来了解Golang调用C语言的方法和技巧。

1、代码结构

新建一个代码工程,创建如下代码文件。

代码语言:txt
复制
-project
--add.h
--add.c
--main.go
--go.mod
--libadd.so

2、源文件

首先,定义C语言程序的头文件 add.h。

  • add.h
代码语言:c
代码运行次数:0
复制
// add.h
#ifndef ADD_H
#define ADD_H

void SayHello();

#endif

然后,定义C语言程序的源文件 add.c。

  • add.c
代码语言:c
代码运行次数:0
复制
// add.c
#include <stdio.h>

void SayHello() {
    printf("Hello from C!\n");
}

最后,定义Golang语言的入口文件 main.go。‌了解Golang语言的小伙伴都知道,main.go文件在 Golang 语言中的作用是作为可执行程序的入口点‌。在 Golang 语言中,一个可执行程序必须包含一个名为 main 的包和一个名为 main 的函数。main.go 文件是包含 main 函数的文件,同时也是程序的入口文件。当我们运行一个 Golang 可执行程序时,操作系统会首先调用 main 函数来启动程序。

  • main.go
代码语言:go
复制
package main

/*
#cgo CFLAGS: -I.
#include "add.h"
*/
import "C"
import "fmt"

func main() {
    fmt.Println("start...")
    C.SayHello() // Call the C function
    fmt.Println("end...")
}

另外,还需要定义 go.mod 文件。这个文件在 Golang 工程中也扮演着重要角色,它是 Golang 语言中的模块管理文件,用于定义和管理 Golang 项目的模块依赖。它是 Go Modules 系统的核心部分,文件记录了项目所依赖的所有模块及其版本信息,确保项目在不同环境下能够稳定、可重复地构建。

  • go.mod
代码语言:javascript
代码运行次数:0
复制
module add

go 1.23.4

3、编译与执行

我们新建 Golang 工程时,需要一些初始化工作,需要指定对应的命令语句:

代码语言:txt
复制
go mod init add
go mod tidy

然后,进行动态库编译,命令如下:

代码语言:txt
复制
go build -buildmode=c-shared -o libadd.so

上述命令是告诉 Golang 编译器生成一个共享库,而不是默认的可执行文件。c-shared 是一种特殊的 build mode,它生成的共享库遵循 C ABI(应用程序二进制接口),使其可以被 C 代码或者其他支持 C ABI 的语言(这里特指 Golang)调用。

编译可执行程序:

代码语言:txt
复制
go build

直接执行 go run -v main.go 文件可能会报错,编译成功后,执行命令:

代码语言:txt
复制
./add

输出结果:

代码语言:txt
复制
start...
Hello from C!
end...

4、明显差异

Golang调用C语言和C++语言存在明显的差异,但是二者的差异这里可以先简单介绍一下。

* 头文件处理

对于 C++,由于其支持名称空间和类等特性,头文件的处理会更复杂。C++ 的头文件可能需要使用 extern “C” 来确保函数名不被C++名称修饰符处理。

* 函数调用约定

C 和 C++ 的函数调用约定不同,这会影响到函数参数的传递和返回值的处理。

* 异常处理

C++ 支持异常处理机制,而 C 不支持。因此,在调用 C++ 代码时,需要考虑如何处理可能抛出的异常。

* C++ 的对象和类

如果你调用的是 C++ 的对象方法,需要创建和管理 C++ 对象。这可能涉及到在 Go 中使用 unsafe 包来操作 C++ 的指针和引用。

* 依赖库

C++ 可能依赖于其他 C++ 库,而这些库可能需要在编译时链接。相比之下,C 程序的依赖通常更简单。

总结

总的来说,虽然调用 C 和 C++ 程序在 Go 中有很多相似之处,但由于 C++ 的复杂性和特性,调用 C++ 程序可能需要更多的注意和处理。今天本文只介绍了Golang调用C语言的示例,下一篇文章会介绍Golang调用C++语言程序的方法。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 1、代码结构
  • 2、源文件
  • 3、编译与执行
  • 4、明显差异
    • * 头文件处理
    • * 函数调用约定
    • * 异常处理
    • * C++ 的对象和类
    • * 依赖库
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档