本帖最后由 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[]){}
命名粉碎查看
以下为输出窗口
|