慕粉1924066901
do_best
这是jni.h头文件里面定义的方法,该方法系统在加载jni的时候会调用该方法,所以动态注册jni方法的时候需要在这个里面进行
慕娘8177184
引入android log的头文件,并连接log库
慕用6123263
https://gitee.com/zxmx/jnidome
蜗牛也是牛232851
我也是这个问题,在c++文件可以include,在头文件里面include就找不到,请您你找到原因了吗
蜗牛也是牛232851
没有,我觉得讲得不错
Hanks73441463
可以新建一个 target_link_libraries 函数,将log日志库与你的其它.cpp编译的动态库链接。
target_link_libraries 内部也会受到排列顺序的影响,将其它.cpp文件编译的动态库名字放在第一个,就可以正常打印log,但是有可能会导致其它库出现 undefined reference 错误。
晨林大师兄0_0
代码在屏幕里啊
qq_慕斯0571903
JNIDynamicLoad.java
public class JNIDynamicLoad {
static {
System.loadLibrary("dynamic-lib");
}
public native int getRandomNum();
public native String getNativeString();
}jni_dynamic_load.cpp
//
// Created by admin on 2020-04-27.
//
#include <jni.h>
#include <cassert>
#include <cstdlib>
#include <iostream>
using namespace std;
jint get_random_num(JNIEnv *env) {
return rand();
}
jstring get_native_string(JNIEnv *env) {
return env->NewStringUTF("jni动态加载的字符串,嘿嘿嘿");
}
/**
* 需要注册的函数列表,放在JNINativeMethod类型的数组中,以后如果需要增加函数,只需在这里添加就行了
* 参数:
* 1、java代码中用native关键字声明的函数名字符串
* 2、签名(传进来参数类型和返回值类型的说明)
* 3、C/C++中对应函数的函数名(地址)
*/
static JNINativeMethod getMethods[] = {
{"getRandomNum", "()I", (void *) get_random_num},
{"getNativeString", "()Ljava/lang/String;", (void *) get_native_string}
};
/**
* 此函数通过调用JNI中 RegisterNatives 方法来注册我们的函数
* @param env
* @param className
* @param methods
* @param nMethods
* @return
*/
static int registerNativeMethods(JNIEnv *env, const char *className, const JNINativeMethod *methods,
jint nMethods) {
jclass clazz;
//找到声明native方法的类
clazz = env->FindClass(className);
if (clazz == NULL) {
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, methods, nMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
static int registerNatives(JNIEnv *env) {
const char *className = "com/example/jnidemo3/load/JNIDynamicLoad";
return registerNativeMethods(env, className, getMethods,
sizeof(getMethods) / sizeof(getMethods[0]));
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
//判断虚拟机状态是否有问题
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
assert(env != NULL);
if (!registerNatives(env)) {
return -1;
}
return JNI_VERSION_1_6;
}CMakeList.txt
add_library(
dynamic-lib
SHARED
jni/jni_dynamic_load.cpp
)
target_link_libraries(
dynamic-lib
${log-lib})如果还有疑惑,可以看我练习的代码
https://github.com/shuiyouwen/JniDemo3
Sun叶为正
恭喜你已经找到源码了
慕粉0734078047
有好多疑点,都没有讲,感觉是个不完整的东西
OSrcD
用java的命令生成so文件
OSrcD
其实本质上是一样的,
在安卓系统或者是linux系统上库的后缀是so,
在windows系统上库的后缀是dll。
只不过在引入库的时候要注意,
一、
System.loadLibrary("native-lib");二、
System.load("/users/xxx/space/native-lib.so");
其中第一个是引入系统环境的库 一个是引入指定目录下的库文件,
两种方法的详情可以自行百度,如果是用java代码引入dll库肯定要使用第二种方式。