如何在Go代码中调用C语言代码?

Go语言是通过自带的一个叫CGO的工具来支持C语言函数调用,同时我们可以用Go语言导出C动态库接口给其它语言使用。

方式一、直接在 Go 代码中写入 C 代码

检查是否开启cgo工具

首先,要查看是否已经开启cgo工具:go env | findstr CGO。若是0则为关闭状态,需要手动开启:set CGO_ENABLED=1

编写main.go文件

随后,新建一个 main.go 文件,在注释中写入 C 语言的代码,并且需要导入 Go 提供的 C 包 import "C"。Go 语言在看到导入这个包之后就知道如何去识别和处理注释中的 C 语言代码了,具体示例如下:

注意 C 代码和 i m p o r t " c " ​​语句之间不能有空行 ! \color{red}{注意C 代码和import "c"​​ 语句之间不能有空行 !} 注意C代码和import"c"​​语句之间不能有空行!

package main// #include <stdio.h>
// #include <stdlib.h>
/*void print_fun(char *s) {printf("print used by C language: %s\n", s);}
*/
import "C"func main() {cStr := C.CString("hello world !") // golang 操作c 标准库中的CString函数C.print_fun(cStr)                  // 调用C函数:print_fun 打印输出
}


这种方式的 C 代码和 Go 代码在同一个文件中,所以大家能明显发现这种方式的代码耦合度太高,仅适用于项目简单单一的情形。

一个更合理的方式应该是 C 代码单独在一个文件。


方式二、Go 直接调用 C 文件

那么,如果已经写好一个封装好的 C 文件代码,Go 语言该如何调用呢?

此时我们需要直接写好 C 相关代码,因为 Go 代码是无法对 C 代码文件进行重写或者修改的。

以如下文件目录结构,创建相关 .h.c.go文件:

C语言 .h 头文件
  • 编写 ​​hello.h​​ 头文件,示例代码如下:
#ifndef HELLO_H
#define HELLO_Hvoid print_fun1(char *s);#endif
C语言 .c 源文件

编写 ​​hello.c​​ 源文件,示例代码如下:

#include "hello.h"
#include <stdio.h>void print_fun1(char *s) {printf("print used by C language: %s\n", s);
}
Go语言 .go 文件

最后编写 ​​main.go​​ 文件:

  • 我们需要在 CFLAGS 参数中填入我们的 GOPath 路径, ​​#cgo CFLAGS: -I xxx​​,xxx这里也可以填写 绝对路径/相对路径
  • 然后在 LDFLAGS 中填入我们的 C 编译后的本地链接文件: ​​#cgo LDFLAGS: xxx/hello.a​​,xxx这里也可以填写 绝对路径/相对路径

注意 C 代码和 i m p o r t " c " ​​语句之间不能有空行 ! \color{red}{注意C 代码和import "c"​​ 语句之间不能有空行 !} 注意C代码和import"c"​​语句之间不能有空行!

具体示例如下:

package main/*
#cgo CFLAGS: -I .
#cgo LDFLAGS: ./hello.a
#include <stdlib.h>
#include <hello.h>
*/
import "C"import ("unsafe"
)func main() {cStr := C.CString("hello world !") // golang 操作c 标准库中的CString函数C.print_fun1(cStr)                 // 调用C函数:print_fun 打印输出defer C.free(unsafe.Pointer(cStr)) // 因为 CSstring 这个函数没有对变量申请的空间进行内存释放
}

编写完以上文件后,距离可运行的程序只有一步之遥了。

编译 c 代码
$ gcc -c *.c         # 生成.o文件$ ar rs hello.a *.o # 生成.a文件
ar: creating archive hello.a$ rm ./hello.o      # 删除已不需要的.o文件,linux下为rm命令,windows下为del命令

生成.a文件需要用到 ar 命令建立或修改备存文件,可参考:Linux ar命令

执行 go 代码
go run main.go

补充

使用了 cStr := C.CString("hello world !"),记得调用C.free(unsafe.Pointer(cStr))释放当前变量申请的内存空间。

可参考:golang 操作c 标准库中的CString函数注意事项

Golang cgo:如何在Go代码中调用C语言代码?相关推荐

  1. python如何用c语言表示_如何在python中调用C语言代码

    原博文 2019-04-03 14:19 − 1.使用C扩展CPython还为开发者实现了一个有趣的特性,使用Python可以轻松调用C代码 开发者有三种方法可以在自己的Python代码中来调用C编写 ...

  2. android开发使用c+_如何在Android项目中开始使用C ++代码

    android开发使用c+ by Onur Tuna 通过Onur Tuna 如何在Android项目中开始使用C ++代码 (How to start using C++ code in your ...

  3. 如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样)

    如何在Python脚本中调用外部命令(就像在linux shell或Windows命令提示符下输入一样) python标准库中的subprocess可以解决这个问题. from subprocess ...

  4. php变量在html调用函数调用,PHP_如何在html标记中调用的函数里传递对象,最近使用jquery结合Ajax开发一个 - phpStudy...

    如何在html标记中调用的函数里传递对象 最近使用jquery结合Ajax开发一个中小型网站应用.在后台管理中要使用Ajax调用系统功能,根据Ajax的返回结果,使用jQuery对前台页面进行操作. ...

  5. 调用c++_WebAssembly: 在C代码中调用JS的函数

    0. 前提知识点 导出C中的函数给JS调用:主要是EMSCRIPTEN_KEEPALIVE这个Emscripten环境特有的宏. #include <stdio.h>#ifndef EM_ ...

  6. php 输出带参数整个html页面,如何在PHP页面中原样输出HTML代码(是该找本php的数来看了)...

    如何在PHP页面中原样输出HTML代码(是该找本php的数来看了) 一.总结 一句话总结:字符串与HTML之间的相互转换主要应用htmlentities()函数来完成. 1.php中的html标签如何 ...

  7. c语言代码中调用系统命令行.sh shell脚本,linux shell system传参

    C语言代码中调用命令行: 1. 使用system(" 命令行 ");    --  执行完命令行后,会返回原先C代码的位置,继续执行. 2. 如果命令行中需要传参,使用 sprin ...

  8. 在python代码中调用vba宏的四种方法

    在python代码中调用vba宏 工作以python为主体,但是遇到了一些word操作的需求(详见上一篇),这个需求用word自带的功能会很容易实现,于是就想着能不能用python调用宏来处理. 网上 ...

  9. c语言调用c 方法,C语言代码中调用C++代码的方法示例

    由于历史原因,以及不同开发人员的技术偏好,C语言和C++语言都有一些独有的非常有价值的项目,因而两种语言的互操作,充分利用前人造的轮子是一件非常有价值的事情. C++代码调用C代码很简单,只要分别在包 ...

最新文章

  1. Gartner预计2018年全球人工智能商业价值将达到1.2万亿美元
  2. LeetCode OJ:Remove Element(移除元素)
  3. JS判断提交表单不能为空 等的验证
  4. 皮一皮:高科技产品真是防不胜防...
  5. 使用angular2 自带的指令,快捷创建服务,组件等!
  6. MATLAB学习笔记(二) -- 矩阵和数组
  7. server 2008中新建AD域控制器
  8. dataframe根据时间戳timestamp切分成多个dataframe
  9. 是的,解禁了,是胜利还是嘲讽?
  10. Visual Studio 2008系列教程(一):VS 2008安装详解!
  11. 大专计算机论文什么方向,大专计算机论文
  12. 【原创】JQWidgets-TreeGrid 1、快速入门
  13. Hystrix组件学习(一)
  14. ttkbootstrap 学习
  15. go mod拉取gitlab私有仓库代码问题最全总结
  16. 用计算机弹出草木,2011-06-06 2010~2011年北京市石景山区普通高中信息技术《信息技术基础》《人工智能初步》—笔试试题(定稿...
  17. 宏油庄冒菜的菜品设置和制作方法
  18. 323、异常访问统计 运维同学最近发现应用的访问日志有异常,需要分析下应用服务器是否被攻击了。
  19. ios 客户端IPV6网络超时等相关问题
  20. augustus预测藻类全基因组序列

热门文章

  1. 2010年11月13日
  2. 总结常用的 JS 功能
  3. 阿里云SSL证书到期怎么办
  4. 用鸢尾花数据集实现knn分类算法
  5. 阿里巴巴举办“马来西亚国家周”,半年帮助2651家小企业!
  6. python中的for in循环有什么意思_for _ in xxx中的下划线_是什么意思?
  7. 数据集可视化工具FACETS
  8. 使用jqprint插件实现打印
  9. 若依RuoYi-Vue前后台框架,下载运行,若依系统生成代码
  10. 2022年最新省份城市json数据