关于JNI

1. 使用
/**
*
*/
package com.magc.jni;

/**
* @author magc
*
*/
public class HelloWorld {
    static {
        System.loadLibrary("Hello");
    }

    public     native void DisplayHello();
    /**
     * @param args
     */
    public static void main(String[] args) {

        new HelloWorld().DisplayHello();
    }

}
2. 如何实现
方案一:Old Style方法
javac ./com/magc/jni/HelloWorld.java

javah -jni com.magc.jni.HelloWorld

在当前目录下生成com_magc_jni_HelloWorld.h头文件,此文件供C、C++程序来引用并实现其中的函数

写一个文件src/jni_helloworldImpl.cpp,用来实现函数

JNIEXPORT void JNICALL Java_com_magc_jni_HelloWorld_DisplayHello


(JNIEnv *env, jobject obj)


{


printf("From jni_helloworldImpl.cpp :");


printf("Hello world ! \n");
return;


}

Then,编译cpp生成so库

方案二:注册native方法

1. 以前在jni中写本地方法时,都会写成 Java_com_example_hellojni_HelloJni_stringFromJNI的形式,函数名很长,而且当类名变了的时候,函数名必须一个一个的改,麻烦。
现在好了有了RegisterNatives,现在一片顶过去五片,蓝瓶的好喝的!
2. hello-jni.c中
  1. #include <string.h>
  2. #include <jni.h>
  3. #include <android/log.h>
  1. #define TAG "HELLO"
  2. #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
  3. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , TAG, __VA_ARGS__)
  4. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__)
  5. #define LOGW(...) __android_log_print(ANDROID_LOG_WARN , TAG, __VA_ARGS__)
  6. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , TAG, __VA_ARGS__)
  1. # define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
  1. jstring native_stringFromJNI( JNIEnv* env, jobject thiz )
  2. {
  3. return (*env)->NewStringUTF(env, "Hello from JNI !");
  4. }
  5. static const char *classPathName = "com/example/hellojni/HelloJni";
  1. static JNINativeMethod methods[] = {
  2. {"stringFromJNI", "()Ljava/lang/String;", (void*)native_stringFromJNI},
  3. };
  1. jint JNI_OnLoad(JavaVM* vm, void* reserved)
  2. {
  3. JNIEnv* env = NULL;
  4. jclass clazz;
  5. //获取JNI环境对象
  6. if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
  7. LOGE("ERROR: GetEnv failed\n");
  8. return JNI_ERR;
  9. }
  10. //注册本地方法.Load 目标类
  11. clazz = (*env)->FindClass(env,classPathName);
  12. if (clazz == NULL)
  13. {
  14. LOGE("Native registration unable to find class '%s'", classPathName);
  15. return JNI_ERR;
  16. }
  17. //注册本地native方法
  18. if((*env)->RegisterNatives(env, clazz, methods, NELEM(methods)) < 0)
  19. {
  20. LOGE("ERROR: MediaPlayer native registration failed\n");
  21. return JNI_ERR;
  22. }
  1. /* success -- return valid version number */
  2. return JNI_VERSION_1_4;
  3. }
a. System.loadLibrary("hello-jni"); 时会调用 JNI_OnLoad
b. RegisterNatives的第二个参数clazz包含了类的路径
c. 定义JNINativeMethod时,第二个参数
    ()中的字符表示参数,后面表示返回值,
    "()V"----> void func()
    "(II)V"----> void func(int, int)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值