全面总结: Golang 调用 C/C++,例子式教程
作者:林冠宏 / 指尖下的幽灵
GitHub : https://github.com/af913337456/
大部分人学习或者使用某样东西,喜欢在直观上看到动手后的结果,才会有继续下去的兴趣。
前言:
Golang 调用 C/C++ 的教程网上很多,就我目前所看到的,个人见解就是比较乱,坑也很多。希望本文能在一定程度上,做到更通俗明了。
下面 golang 简称 go , 一如既往,少说废话,我们现在开始。
go 调用 c/c++ 函数的实现方式有:
- 直接
嵌套在go文件中使用,最简单直观的 - 导入
动态库 .so 或 dll的形式,最安全但是很不爽也比较慢的 - 直接引用 c/c++ 文件的形式,层次分明,容易随时修改看结果的
第三个直接引用 c/c++ 文件的形式 是我要介绍的重点。
需要的环境支持
- Linux 具备 gcc 与 g++ 即可
- Windows 需要安装 mingw,否则编译时会有这类错:
cannot find -lmingwex - Mac 参考 Linux
1,直接嵌套在go文件
package main
/*
// C 标志io头文件,你也可以使用里面提供的函数
#include <stdio.h>
void pri(){
printf("hey");
}
int add(int a,int b){
return a+b;
}
*/
import "C" // 切勿换行再写这个
import "fmt"
func main() {
fmt.Println(C.add(2, 1))
}
上面的代码,直接拷贝运行就能输出结果:3
结论:
- 但凡要引用与 c/c++ 相关的内容,写到 go 文件的头部
注释里面 - 嵌套的 c/c++ 代码必须符合其语法,不与 go 一样
import "C"这句话要紧随,注释后,不要换行,否则报错- go 代码中调用 c/c++ 的格式是:
C.xxx(),例如 C.add(2, 1)
2,导入动态库 .so 或 .dll 的形式
假设项目目录如下
|-project
| |-lib
| | |-libvideo.dll
| | |-libvideo.so
| |-include
| | |-video.h
| |-src
| | |-main.go
头文件 .h 如下面这样
//video.h
#ifndef VIDEO_H
#define VIDEO_H
void exeFFmpegCmd(char* cmd); // 声明
#endif
源文件 .c 如下面这样
#include <stdio.h>
#include "video.h"
void exeFFmpegCmd(char* cmd){ // 实现
// ....
printf("finish");
}
使用 gcc 或 g++ 生成 .so库,或 win 下生成 dll
例如: gcc video.c -fPIC -shared -o libvideo.so
最后 main.go
把动态库放到一个你喜欢的目录,也可以放到当前项目里面,像上面列出的例子一样。再引用
package main
/*
#cgo CFLAGS: -Iinclude
#cgo LDFLAGS: -Llib -llibvideo
#include "video.h"
*/
import "C"
import "fmt"
func main() {
cmd := C.CString("ffmpeg -i ./xxx/*.png ./xxx/yyy.mp4")
C.exeFFmpegCmd(&cmd)
}
先回答为什么说这种是最安全的和最不爽的?原因如下:
- 动态库破解十分困难,如果你的 go 代码泄露,核心动态库没那么容易被攻破
- 动态库会在被使用的时候被加载,影响速度
- 操作难度比方式一麻烦不少
结论
CFLAGS: -I路径这句话指明头文件所在路径,-Iinclude 指明 当前项目根目录的 include 文件夹LDFLAGS: -L路径 -l名字指明动态库的所在路径,-Llib -llibvideo,指明在 lib 下面以及它的名字 video- 如果动态库不存在,将会爆
找不到定义之类的错误信息
3,直接引用 c/c++ 文件的形式 (重点)
假设项目目录如下
|-util
| |-util.h
| |-util.c
| |-util.go
util.h
int sum(int a,int b);
util.c
#include "util.h"
int sum(int a,int b){
return (a+b);
}
util.go
package util
/*
#include "util.c"
*/
import "C"
import "fmt"
func GoSum(a,b int) int {
s := C.sum(C.int(a),C.int(b))
fmt.Println(s)
}
这样调用 main.go
package main
func main(){
util.GoSum(4,5)
}
第三种方式便是如此简洁明了。
最后,补充一下,一般需要 go 调用 c/c++ 的,主要是使用一些著名的开源库,例如 ffmpeg,opencv,等这些源码是基于 c/c++ 语言的,除此之外还有一个很重要的点,便是运行速度!
完
全面总结: Golang 调用 C/C++,例子式教程的更多相关文章
- Golang 调用 C/C++,例子式教程
大部分人学习或者使用某样东西,喜欢在直观上看到动手后的结果,才会有继续下去的兴趣. 前言: Golang 调用 C/C++ 的教程网上很多,就我目前所看到的,个人见解就是比较乱,坑也很多.希望本文能在 ...
- golang调用c++的dll库文件
最近使用golang调用c++的dll库文件,简单了解了一下,特作此笔记:一.DLL 的编制与具体的编程语言及编译器无关 dll分com的dll和动态dll,Com组件dll:不管是何种语言写的都可以 ...
- Golang调用windows下的dll动态库中的函数
Golang调用windows下的dll动态库中的函数 使用syscall调用. package main import ( "fmt" "syscall" & ...
- golang生成c-shared so供c语言或者golang调用到例子
1.golang生成c-shared类型到so 建立文件夹hello,创建main.go文件,内容如下 package main import "C" func main() {} ...
- LevelDB性能测试|Golang调用LevelDB
LevelDB性能测试|Golang调用LevelDB 不同方式使用压力测试 用ssdb,TCP连接方式调用,底层存储levelDB 直接调用Cgo的levelDB (必须保证串行) 直接调用Gola ...
- Golang调用Python
https://yq.aliyun.com/articles/117329 Python是时髦的机器学习御用开发语言,Golang是大红大紫的新时代后端开发语言.Python很适合让搞算法的写写模型, ...
- golang调用c动态库
golang调用c动态库 简介 golang调用c语言动态库,动态方式调用,可指定动态库路径,无需系统目录下 核心技术点 封装c动态库 go语言调用c代码 实例代码 封装c动态库 头文件 test_s ...
- Golang 调用 aws-sdk 操作 S3对象存储
Golang 调用 aws-sdk 操作 S3对象存储 前言 因为业务问题,要写一个S3对象存储管理代码,由于一直写Go,所以这次采用了Go,Go嘛,快,自带多线程,这种好处就不用多说了吧. 基础的功 ...
- Golang调用Dll案例
Golang调用Dll案例 前言 在家办公已经两个多星期了,目前最大的困难就是网络很差.独自一个人用golang开发调用dll的驱动程序.本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心.本想依 ...
随机推荐
- springboot学习笔记-4 整合Druid数据源和使用@Cache简化redis配置
一.整合Druid数据源 Druid是一个关系型数据库连接池,是阿里巴巴的一个开源项目,Druid在监控,可扩展性,稳定性和性能方面具有比较明显的优势.通过Druid提供的监控功能,可以实时观察数据库 ...
- 个推demo
官网文档更详细,这里是只做个测试 http://docs.getui.com/server/java/start/ 全部推送(针对app应用) public static final String a ...
- Mixed Reality-宁波市VR/AR技术应用高研班总结
年,全球AR与VR市场规模将达到1500亿美元,而根据市场研究机构BI Intelligence的统计,2020年仅头戴式VR硬件市场规模将达到28亿美元,未来5年复合增长率超过100%.本次培训从V ...
- 【java】method.invoke(方法底层所属对象/null,new Object[]{实际参数})
反射调方法时无论是静态/非静态,固定/可变参数,都有Object对象数组对参数进行包装. package com.tn.clas; import java.lang.reflect.Method; i ...
- android studio 环境变量配置
1.需要添加path环境变量: 2.真机调试或模拟器调试需要启动adb adb kill-severadb -start-server可能有端口冲突--重启或者修改端口 创建密匙http://blog ...
- 用keras作CNN卷积网络书本分类(书本、非书本)
本文介绍如何使用keras作图片分类(2分类与多分类,其实就一个参数的区别...呵呵) 先来看看解决的问题:从一堆图片中分出是不是书本,也就是最终给图片标签上:“书本“.“非书本”,简单吧. 先来看看 ...
- CSS3关于过渡效果的问题
首先trasition:transform只是单单表示后面只要有含有的tranform的所有属性可以参与动画,而trasition:all表示后面所有动画属性都可以参动画,当父容器有relative时 ...
- PHP判断手机号运营商(详细介绍附代码)
道理很简单,知道手机号规则 进行正则判断就可以 移动:134.135.136.137.138.139.150.151.157(TD).158.159.187.188 联通:130.131.132.15 ...
- 安全扫描工具 Netsparker
Netsparker是一款web应用安全漏洞扫描工具 Netsparter官网:https://www.netsparker.com/web-vulnerability-scanner/,与其他安全扫 ...
- c# 去除字符串中重复字符
String.Join 和 Distinct 方法 https://www.cnblogs.com/louby/p/6224960.html 1.在写程序中经常操作字符串,需要去重,以前我的用方式利用 ...