so

脑洞型so加载过程实验

人走茶凉 提交于 2020-11-02 16:37:34
1.文章难易度【★★★★★】 2.文章作者:penguin_wwy 3.本文参与 i春秋社区 原创文章奖励计划,未经许可禁止转载 4.阅读基础:熟悉Android虚拟机源码、so加载过程、Native编程 【预备~~~起】 前几天有人在群里问,ELF的可执行文件能不能调用so文件的JNI_OnLoad函数。这倒是一个有脑洞的想法,我尝试了一夜,就把尝试的过程记录下来。 【一二三四】 先从理论上分析一下可能性,对于so文件我们在代码里是可以dlopen函数打开,然后dlsym函数定位so文件中的函数地址执行调用的。也就是说只要我们可以解决参数问题,调用so文件中的任意函数都是可以的。 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved); 这是jni.h中JNI_OnLoad函数的声明,对于第二个参数我们可以不管。第一个参数是一个虚拟机实例。在正常的APK调用so的过程中,Java层会将自己的JavaVM传递到JNI_OnLoad中,通过JavaVM对象中的函数表中的GetEnv,可以获得JNIEnv对象,JNIEnv对象的函数表中保存了我们在编写so代码中经常用到的函数如NewStringUTF,该函数接受一个char *字符串转化为jstring字符串。也就是说

用gcc编译成动态链接库的方法

末鹿安然 提交于 2020-02-29 03:14:52
通过一个例子来介绍如何生成一个动态库。假设有一个头文件so_test.h和三个C文件:test_a.c、test_b.c、test_c.c /* so_test.h */ #include <stdio.h> #include <stdlib.h> void test_a(); void test_b(); void test_c(); /* test_a.c */ #include "so_test.h" void test_a(){ printf("this is in test_a...\n"); } /* test_b.c */ #include "so_test.h" void test_b(){ printf("this is in test_b...\n"); } /* test_c.c */ #include "so_test.h" void test_c(){ printf("this is in test_c...\n"); } 将这几个文件编译成一个动态库:libtest.so gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so 参数说明: -shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接

Android Studio打包.so文件教程

。_饼干妹妹 提交于 2020-01-07 18:07:37
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 在eclipse里,.so文件eclipse会帮助我们自动打包进apk文件,通常是放在:libs/armeabi目录,然后把libxxx.so拷贝到这个目录下,这样NDK就会自动把这个libxxx.so打包进apk,安装 apk 后位置是在放在your_apk_package_name/lib/目录下。 android studio就有些不同了,下面给大家介绍一下,方法很简单,一学就会。 这里给大家介绍三种方法,来自网络和QQ群: 1.来自 网页 : 将需要打包进apk内的so文件放入项目文件夹下的libs目录,然后在app内(注意是app内的,不是project的)的build.gradle中的android { }中添加如下代码 <span style="font-size:14px;"><span style="font-size:14px;">sourceSets { main { jniLibs.srcDirs = ['libs'] } }</span></span> 添加后是这样的(仅为范例): <span style="font-size:14px;">apply plugin: 'android' android { compileSdkVersion 19 buildToolsVersion

【转】关于Android的.so文件你所需要知道的 (一)

心不动则不痛 提交于 2019-12-06 08:14:39
原文链接 早期的Android系统几乎只支持ARMv5的CPU架构,你知道现在它支持多少种吗?7种! Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。应用程序二进制接口( A pplication B inary I nterface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android 系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64- v8a,mips64,x86_64。 为什么你需要重点关注.so文件 如果项目中使用到了NDK,它将会生成.so文件,因此显然你已经在关注它了。如果只是使用Java语言进行编码,你可能在想不需要关注.so文 件了吧,因为Java是跨平台的。但事实上,即使你在项目中只是使用Java语言,很多情况下,你可能并没有意识到项目中依赖的函数库或者引擎库里面已经 嵌入了.so文件,并依赖于不同的ABI。 例如,项目中使用RenderScript支持库,OpenCV,Unity,android-gif-drawable

关于安卓so的兼容性的简单说明

时光毁灭记忆、已成空白 提交于 2019-12-06 07:55:18
armeabi、armeabi-v7a、mips、x86 、 arm64-v8a 如何理解? ABI:指应用基于哪种指令集来进行编译,ABI以前总共有四种,分别是armeabi、armeabi-v7a、mips、x86,它们都是表示cpu的类型,现在又有了arm64-v8a。 (注意:以下所有讨论不包括mips) 先说以前对于so的平台兼容处理方式吧。 以前安卓都是32位系统,运行的进程都是32位,理论上armeabi的so可以被全平台兼容,所以,理论上我们可以只提供一个armeabi的so就能在所有cpu平台运行了。也就是说如果我们引入了A和B两个库,其中A提供了全平台的 armeabi、armeabi-v7a、x86三 个so,而B只有一个armeabi的so,那么我们可以把B的这个so复制到其他两个文件夹就可以被兼容了。 同时因为现在armeabi的设备比armeabi-v7的要少很多,所以有些应用直接提供了armeabi-v7的so。 现在有了arm64-v8a的CPU以及安卓64位系统,上面的方法就有点例外了。 在安卓64位系统上,同时运行着32位和64位的进程(这点和Windows很像,在64位Windows上也是能同时运行32位和63位的进程的)。 以下讨论是基于64位安卓系统上: 如果一个纯粹的java写的应用,没有使用任何的so,那么默认就应该以64位模式来运行;

Python调用C/C++的种种方法

做~自己de王妃 提交于 2019-11-30 09:24:22
Python调用C/C++的种种方法 Python是解释性语言, 底层就是用c实现的, 所以用python调用C是很容易的, 下面就总结一下各种调用的方法, 给出例子, 所有例子都在ubuntu9.10, python2.6下试过. 1. Python 调用 C (base) 想在python中调用c函数, 如这儿的fact #include <Python.h> int fact(int n) { if (n <= 1) return 1; else return n * fact(n - 1); } PyObject* wrap_fact(PyObject* self, PyObject* args) { int n, result; if (! PyArg_ParseTuple(args, "i:fact", &n)) return NULL; result = fact(n); return Py_BuildValue("i", result); } static PyMethodDef exampleMethods[] = { {"fact", wrap_fact, METH_VARARGS, "Caculate N!"}, {NULL, NULL} }; void initexample() { PyObject* m; m = Py_InitModule(

【转】关于Android的.so文件你所需要知道的(二)

妖精的绣舞 提交于 2019-11-26 11:08:48
Androidndk开发打包时我们应该如何注意平台的兼容(x86,arm,arm-v7a) 很多朋友在开发Android JNI的的时候,会遇到findlibrary returned null的错误,因为某种原因,so没有打包到apk中。下面浅析下引起该错误的原因以及平台兼容性问题。 一、没有将so打包到apk中的原因。 当你发现到findlibrary returned null的错误时,其实最直接的解决办法就是解压apk,看看apk中的x86、armeabi、armeabi-v7a文件夹中是否有对应的so,此时你可能在对应的文件夹下发现少了so,然后再去查原因即可。 一般有两方面的原因: 1.apk中有对应平台的文件夹,但是文件夹里却没有对应的so。 举个例子,apk中lib下面一旦出现x86文件夹,程序运行的时候就会去加载x86对应的库,但是如果此时x86文件夹没有将so放进来,则会遇到报错。 2.第三方对平台的兼容策略与自己不一致。 可能第三方选择了只支持armeabi(假设某支付sdk),但是我们的游戏在Application.mk中配置了APP_ABI := all,如此,我们的游戏打包出 了所有平台的so,但是第三方却只有armeabi文件夹对应的so,造成程序运行异常,这种情况在开发期间最常见,一些小公司由于测试人员不足或者测试设备不足