Golang开发动态库的实现
对于一个Golang开发者来说,牢固扎实的基础是十分重要的,golang学习网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《Golang开发动态库的实现》,主要介绍了动态库,希望对大家的知识积累有所帮助,快点收藏起来吧,否则需要时就找不到了!
我们平时使用的动态库都是由C/C++开发最后生成的.so文件。
可以先看看一个JNI的开发过程。
一. 开发JNI
有两种方式,现在一种比较快的方式是AndroidStudio你在创建项目选择Module的时候它会给你个JNI的模板,直接使用那个就行。
但是我还是比较喜欢传统的方法。
简单来说传统的方式就是你用命令来把java文件变成C++的头文件
简单演示一遍,先写个java类
public class TestJni {
static {
System.loadLibrary("KylimTest");
}
public static native String getMsg();
}
定义了一个native修饰的方法,在代码调用这个方法之后JNI就会自动调用到动态库中相应的方法。
将这个类用命令生成头文件,来到文件夹路径下输入命令
javah -jni 包名.类名
可以看到默认会生成一个.h的头文件,自动命名为 包名_类名.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include/* Header for class com_kylim_nativetest_TestJni */ #ifndef _Included_com_kylim_nativetest_TestJni #define _Included_com_kylim_nativetest_TestJni #ifdef __cplusplus extern "C" { #endif /* * Class: com_kylim_nativetest_TestJni * Method: getMsg * Signature: (I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_kylim_nativetest_TestJni_getMsg (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
主要的核心就是这句
JNIEXPORT jstring JNICALL Java_com_kylim_nativetest_TestJni_getMsg (JNIEnv *, jclass);
其它的我也不清楚,都是C相关的, 如果你嫌用命令生成麻烦,你可以自己创建一个.h文件然后方法命名就按照这样的规范去写
头文件只是为了定义,我们需要自己写原文件,所以要创建一个.cpp结尾的文件
#include "com_kylim_nativetest_TestJni.h"
JNIEXPORT jstring JNICALL Java_com_kylim_nativetest_TestJni_getMsg
(JNIEnv *env, jclass cls){
jstring result = env->NewStringUTF("结果是");
return result;
}
方法命名是有规范的,看Demo也知道怎么规范了,没必要多解释,这样两端的代码就写完了,但是仅仅这样是无法运行项目的。
还需要些一些配置,因为在AndroidStudio中是Gradle去帮我们编译C++的代码,所以需要写这些配置。如果你不是用AS开发,你用其它工具开发直接生成.so文件再丢进AS中的话,可以忽略这一步。
先看看我的Jni目录

要创建一个Android.mk
#固定写法 LOCAL_PATH:=$(call my-dir) #固定写法 include $(CLEAR_VARS) #生成so名称 LOCAL_MODULE := KylimTest LOCAL_SRC_FILES := testone.cpp #固定写法 include $(BUILD_SHARED_LIBRARY)
具体的配置可自行去查找,这里不是主要讲JNI的,所以就不讲这么细。
还需要一个Application.mk
# 选择不同的 ABI,多个使用空格作为分隔符,全部是all # APP_ABI := armeabi armeabi-v7a APP_ABI := armeabi-v7a # 指定要使用的运行时 APP_STL := c++_static
当然这样还不行,都说了是Gradle进行编译,那么肯定还要在Gradle中写一些配置
android {
defaultConfig {
ndkBuild {
//指定 Application.mk 的路径
arguments "NDK_APPLICATION_MK:=src/main/jni/Application.mk"
//指定生成哪些平台的 so 文件
abiFilters "armeabi-v7a"
//cFlags 和 cppFlags 是用来设置环境变量的, 一般不需要动
cFlags "-DTEST_C_FLAG1", "-DTEST_C_FLAG2"
cppFlags "-DTEST_CPP_FLAG2", "-DTEST_CPP_FLAG2"
}
}
sourceSets { main { jni.srcDirs = ['src/main/jni'] } }
externalNativeBuild {
ndkBuild {
path file('src/main/jni/Android.mk')
}
}
}
这样就能简单的跑一个JNI的Demo,总的来说就是Java这边写一个类定义一些native方法和加载,C++这边写具体的方法实现。
二.用Go开发动态库
上面说的原生方法是用C/C++进行开发的,那么如果你不会C++的话怎么办,C++的学习也并非这么容易,就拿两边的类型来说,一开始新手肯定会碰到类型转换的问题,往往会先劝退一些人,但是Go不一样,有Java基础的话学起go还是挺快的。
那么用Go开发的动态库是怎样的?也是SO文件吗,是不是也像C++一样,编译后经过某步操作生成SO文件。
我看到网上有些文章确实是写怎么生成so的,但是说得太少,感觉不可靠,直到我看到官方有写。

可以在官方中看到是有一个mobile的库的
https://github.com/golang/mobile
读下去它会指引你去wiki
https://github.com/golang/go/wiki/Mobile

可以看出它会打出一个aar的文件,那么aar对于我们接入来说确实很方法,但我很想探究这个aar里面究竟是什么,所以我们需要打出一个aar然后解压看看它里面到底是什么
这里先说一下,下载这个库之前,你本地肯定先要配置好Go的环境
然后按照这里的流程就行下载
go get -d golang.org/x/mobile/example/basic
但这输入这条命令需要科学上网的方式才能下载,总的来说很麻烦。
所以我们可以直接克隆mobile的库,就是上面的这个链接 https://github.com/golang/mobile
直接下载下来,除此之外,还需要tools,这些都在Go中,链接 https://github.com/golang/tools
将这两个下载下来,然后拷贝到你的Go的以下路径
go/src 创建一个文件夹golang.org/x ,把这两个文件夹丢进去
然后输入命令
gomobile init
可以输入命令 查看安装配置是否成功
gomobile bind -help
如果配置成功会给你一些提示

我感觉文档写得还是不算清楚,但是它有告诉你用什么命令生成aar
gomobile bind -o app/hello.aar -target=android golang.org/x/mobile/example/bind/hello
你在GoPath中创建一个Go文件,我是用GoLand进行开发的,项目的目录设置成GoPath,编写完之后,可以直接在文件中运行
gomobile bind -o 输入文件名.aar -target=android
这样就能在文件夹中生成一个aar
接着我们看看aar里面是什么,解压

首先可以看到生成这些ABI的so文件,再看看Manifest

这里有限制最低版本,所以如果你的版本比他还低的话就需要注意一下了
然后res里面是可以看到没有文件的。
最后我们反编译class文件

因为这不是Demo,直接是写公司的项目,所以有些地方要码,但是不影响。
从这里看得出,go帮我们生成了一个java文件,这个java文件定义了再Go中命名的原生方法。
其实从这里就可以看出,Go用的也基本是我们最上面写的JNI的方法,只是他帮你封装起来了而已
但是他的原生代码是不是转成C++的我就不清楚了,因为我不会反编译SO文件。
终于介绍完啦!小伙伴们,这篇关于《Golang开发动态库的实现》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!
如何利用Golang解析读取Mysql备份文件
- 上一篇
- 如何利用Golang解析读取Mysql备份文件
- 下一篇
- golang 网络框架之gin的使用方法
-
- 淡然的老鼠
- 这篇博文出现的刚刚好,大佬加油!
- 2023-01-03 07:59:27
-
- 聪明的书本
- 这篇博文出现的刚刚好,太细致了,写的不错,收藏了,关注老哥了!希望老哥能多写Golang相关的文章。
- 2023-01-02 21:47:02
-
- 123654
- 这篇技术贴真及时,很详细,受益颇多,码住,关注大佬了!希望大佬能多写Golang相关的文章。
- 2022-12-29 16:31:06
-
- 生动的抽屉
- 真优秀,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢作者分享文章内容!
- 2022-12-26 15:53:35
-
- 天真的玉米
- 好细啊,已收藏,感谢作者大大的这篇博文,我会继续支持!
- 2022-12-26 12:45:20
-
- Golang · Go教程 | 17小时前 | 并发 · Go教程 · trace.NewTask go tool trace Go runtime/trace 执行跟踪 trace.WithRegion
- Go runtime/trace 怎样按任务标记跟踪区间
- 391浏览 收藏
-
- Golang · Go教程 | 18小时前 | flag · go · Go 命令行参数 flag.TextVar encoding.TextUnmarshaler
- Go flag.TextVar 怎样把自定义类型接入命令行
- 184浏览 收藏
-
- Golang · Go教程 | 19小时前 | 错误处理 · 模板 · Go教程 · html/template · 模板渲染 Go html/template missingkey 模板缺失字段 Execute错误
- Go html/template 缺失字段的严格渲染配置与错误处理
- 371浏览 收藏
-
- Golang · Go教程 | 19小时前 | html · go · 模板 · url · Go html/template 自动转义 URL上下文 template.URL
- Go html/template 怎样避免 URL 上下文误用
- 326浏览 收藏
-
- Golang · Go教程 | 19小时前 |
- Go text/template.ParseFS 怎样加载嵌入文件模板
- 208浏览 收藏
-
- Golang · Go教程 | 19小时前 |
- Go database/sql.NamedArg 怎样给 SQL 参数命名
- 311浏览 收藏
-
- Golang · Go教程 | 19小时前 | HTTP · go · Gin · Gin ShouldBindBodyWith 请求体重复绑定 ShouldBind binding.JSON
- Gin ShouldBindBodyWith 怎么让同一个请求体绑定两次
- 134浏览 收藏
-
- Golang · Go教程 | 20小时前 | go · 文件系统 · Go os.ReadDir Go File.ReadDir Go DirEntry Go 目录遍历
- Go os.ReadDir 怎样高效读取目录条目
- 269浏览 收藏
-
- Golang · Go教程 | 20小时前 | go · Go go/types.Config Go Importer Go 类型检查 types.Check
- Go go/types.Config 怎样给类型检查接入导入器
- 222浏览 收藏
-
- Golang · Go教程 | 20小时前 |
- Go maphash.Hash 怎样用固定种子复现哈希结果
- 341浏览 收藏
-
- Golang · Go教程 | 20小时前 | Go 字节切片 encoding/binary AppendByteOrder
- Go binary.ByteOrder.Append 怎样把整数追加到现有字节切片
- 373浏览 收藏
-
- Golang · Go教程 | 21小时前 | go · IPv6 Go ipv4 netip.ParsePrefix CIDR
- Go netip.ParsePrefix 怎样解析 CIDR 字符串
- 334浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 573次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 616次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 646次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 605次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 422次使用
-
- 解决GO编译时避免引入外部动态库的问题
- 2022-12-22 263浏览
-
- golang调用c语言动态库方式实现
- 2023-01-12 377浏览

