C/C++知识点之全面总结: Golang 调用 C/C++,例子式教程
小标 2018-12-03 来源 : 阅读 956 评论 0

摘要:本文主要向大家介绍了 C/C++知识点之全面总结: Golang 调用 C/C++,例子式教程,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了 C/C++知识点之全面总结: Golang 调用 C/C++,例子式教程,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

大部分人学习或者使用某样东西,喜欢在直观上看到动手后的结果,才会有继续下去的兴趣。
前言:
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  

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 
#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++ 语言的,除此之外还有一个很重要的点,便是运行速度!

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程