A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 ylca 于 2016-8-5 05:22 编辑

以下东西仅为个人理解! 如有错误之处 请前辈们指正
学习JNI过程中发现 So是一个类似 window平台的Dll !! 但是window上的DLL是能随便加载的 那So呢!!  Android中加载So看似简单但并不是所以功能都要在java中实现的 有时候功能要在C++上实现 ,那就需要在C++上加载别人的So文件了!直接上代码把 我自己写了两个 SO文件  名称为 libloadSo.so 和 libmyso.so
[Java] 纯文本查看 复制代码
public class MainActivity extends Activity {
//加载So文件
        static{
                System.loadLibrary("loadSo");
        }
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        
        }
        public void click(View v) {
//我把libmyso.so 放在了Cache目录下  C++中不好获取路径 我就直接从这里传过去
                File file  = new File(getCacheDir(),"libmyso.so");
//调用本地方法
                System.out.println(returnChar(file.getPath()));
                System.out.println(returnint(file.getPath()));
        }
        public native  String returnChar(String path);
        public native  int returnint(String path);
}

[C++] 纯文本查看 复制代码
//libloadSo.so 源码
#include <jni.h>
#include <dlfcn.h>
#include "loadSo.h"
#include <stdlib.h>

typedef char* (*RETURNCHAR)(char*);
typedef int (*RETURNINT)(int);
JNIEXPORT jstring JNICALL Java_com_ylca_loadso_MainActivity_returnChar
  (JNIEnv *env, jobject thiz,jstring path){
        //加载so文件  
        void *handle = dlopen(jstringToCahr(env,path), RTLD_NOW);
        if(handle==0){
                return env->NewStringUTF("加载失败");
        }else{
                //获取函数指针   _Z10returnCharPc 这里为returnChar 的真实函数名  被C++命名粉碎      NDK中有工具可以查看   图片在下面
                RETURNCHAR returnChar = (RETURNCHAR)dlsym(handle,"_Z10returnCharPc");
                //执行并且返回
                return env->NewStringUTF(returnChar("走一遍把"));
        }

}
JNIEXPORT jint JNICALL Java_com_ylca_loadso_MainActivity_returnint
  (JNIEnv *env, jobject thiz,jstring path){
        //加载so文件
        void *handle = dlopen(jstringToCahr(env,path), RTLD_NOW);
                if(handle==0){
                        return -1;
                }else{
                        //获取函数指针  这里为_Z9returnInti 的真实函数名  被C++命名粉碎
                        RETURNINT returnInt = (RETURNINT)dlsym(handle,"_Z9returnInti");
                        //执行 returnChar
                        int result = returnInt(10086);
                        return result;
                }

}
//此处为String转 char
char* jstringToCahr(JNIEnv* env, jstring jstr) {
        char* rtn = NULL;
        jclass clsstring = env->FindClass("java/lang/String");
        jstring strencode = env->NewStringUTF("utf-8");
        jmethodID mid = env->GetMethodID(clsstring, "getBytes","(Ljava/lang/String;)[B");
        jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
        jsize alen = env->GetArrayLength(barr);
        jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
        if (alen > 0) {
                rtn = (char*) malloc(alen + 1);
                memcpy(rtn, ba, alen);
                rtn[alen] = 0;
        }
        env->ReleaseByteArrayElements(barr, ba, 0);
        return rtn;
}
[C++] 纯文本查看 复制代码
//libmyso.so   源码 因为只是演示作用 没写什么就直接把传入的参数返回
#include <stdio.h>
char* returnChar(char*  cstr){return cstr;}

int returnInt(int  i){return i;}

void returnVoid(){}

int main(int argc, char* argv[]){}


命名粉碎查看

以下为输出窗口






1 个回复

倒序浏览
{:2_30:}!!!!!!!!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马