Android平台调用so库中函数的流程及一些坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhou12314/article/details/75193965

一.Android平台如果要调用一些C/C++语言的所编译生成的库的函数一般要进行一下几个步骤。


     1.确保我们的so库是用 ndk 或者 arm-linux-androideabi-gcc编译而成,如何编译参考上一篇文章。


     2.如果我们的安卓应用程序是在studio中开发用java所写,那么我们 需要配置以下内容:


a:  去Android官网下载NDK并配置到我们的studio中,gradle.properties文件中加上一句:

android.useDeprecatedNdk=true //不加有可能导致编译不成功

b:  因为我们是用java调用c/c++,需要我们需要使用jni,创建一个类并实现Jni规范中本地方法

public class NdkTest {
    static {
        System.loadLibrary("NdkTest");  //我们要生成的so库的名字,前缀和后缀名去掉
    }

    public static native String myAdd(); //我们java调用c所实现的jni方法,我们要做的就是在这个jni函数中去调用没有jni规范的c/c++函数
}

               

c:在studio这rebuild,为这一个类生成.class文件


                d:调用jdk中的javah,为这个.class文件生成一个.h文件


                e:在我们app目录下创建jni文件夹,将.h文件放入,并创建.c或者.cpp文件去实现我们的.h中的函数,在这些函数中我们就可以调用第三方的so库了


                f:将第三方so或者第三方的c源码及我们的.h一同放入jni目录下,并书写Android.mk 及  Application.mk文件,进行编译规程的书写,至于如何写mk文件,可以参考上一篇文章或者自行百度,有海量的资料。


                g:书写过mk文件之后我们可以直接在stdio下调用命令行进行ndk-build编译,会在libs目录下生成.so文件,注意我们studio默认寻找的路径是jnilibs,如果不想改gradle的话可以直接在jni下创建jnilibs目录,将.so放入,这是一个坑,一定要注意。


                h:编译完成以后我们就可以直接在类中直接调用我们刚开始定义的native方法进行与c语言的通信了。


     3.如果我们的Android应用是在qt中用c++开发的话,因为没有涉及到jni,所以简单很多:


                 a: 将用我们编译好的so库直接在pro文件中LIB中进行引用,或者直接调用项目,在build apk 选项中,有add library中进行添加。


                 b:将.h在.pro中进行引入。


                 c:直接在.cpp中直接调用就可以了。


  e:没事了,就是这么方面。



二: 碰到的一些坑


             1.在我们jni实现的函数中如果去调用so中的函数,一定要用dlopen、dlsym、dlclose去查找so及加载so中的函数,切记切记,我在这上面吃了很大的亏。


             2.利用javah生成.h文件的时候,一定要 cd到你Android工程的bin/classes目录下,包含完整类名,不带.class。


             3.加载so的顺序一定要注意,一定要注意。


             4.注意一些jni类型的数据的转换。



猜你喜欢

转载自blog.csdn.net/zhou12314/article/details/75193965