您的位置:首页 > 编程语言 > Java开发

JNI学习(一)(c和java层对象互相调用)

2017-10-12 10:18 337 查看

c层调用java对象

package com.example.bean;

/**
*
* java对象
* @author telenewbie
*
*/
public class JNI_cCalljava_test {

public static int num = 0;

private String name;

public static int intMethod(int n) {
num = n * n;
return num;
}

public static boolean booleanMethod(boolean bool) {
return !bool;
}

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

}


#include <com_example_test_TestJava.h>
#include <jni.h>
#include <stdio.h>

#ifdef ANDROID
#include <jni.h>
#include <android/log.h>
#define LOGE(format, ...)  __android_log_print(ANDROID_LOG_ERROR, "(>_<)", format, ##__VA_ARGS__)
#define LOGI(format, ...)  __android_log_print(ANDROID_LOG_INFO,  "(^_^)", format, ##__VA_ARGS__)
#else
#define LOGE(format, ...)  printf("(>_<) " format "\n", ##__VA_ARGS__)
#define LOGI(format, ...)  printf("(^_^) " format "\n", ##__VA_ARGS__)
#endif

//直接为java对象进行赋值
void test(JNIEnv * env, jobject object) {
jint square;
//在c代码里面调用java代码里面的方法
// java 反射
//1 . 找到java代码的 class文件
//    jclass      (*FindClass)(JNIEnv*, const char*);
jclass dpclazz = (*env)->FindClass(env,
"com/example/bean/JNI_cCalljava_test");
if (dpclazz == 0) {
LOGI("find class error");
return;
}
LOGI("find class ");

//2 寻找class里面的方法,(此处为静态方法)
//   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID method1 = (*env)->GetStaticMethodID(env, dpclazz, "intMethod",
"(I)I");
if (method1 == 0) {
LOGI("find method1 error");
return;
}
LOGI("find method1 ");
//3 .调用这个方法(因为调用的是静态方法传递类名即可,如果是对象,则需要更改方式)
//    void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
square = (*env)->CallStaticIntMethod(env, dpclazz, method1, 5);
LOGI("output %d",square);
}

JNIEXPORT jstring JNICALL Java_com_example_test_TestJava_speak(JNIEnv * env,
jobject object) {
LOGI("dufresne Hello World From libhelloworld.so!");
test(env, object);
return (*env)->NewStringUTF(env, "Hello World! I am Native interface");
}

//使用反射为对象赋值,返回java层的对象
JNIEXPORT jobject JNICALL Java_com_example_test_TestJava_getMyClass(
JNIEnv * env, jobject obj, jint age, jstring name) {
jclass cls = (*env)->FindClass(env, "com/example/bean/MyClass");
if (cls == 0) {
LOGE("find MyClass Error");
return NULL;
}
jobject dpobj = (*env)->AllocObject(env, cls);

LOGI("obj=%d,dpobj=%d",obj,dpobj);

jmethodID method1 = (*env)->GetMethodID(env, cls, "setName",
"(Ljava/lang/String;)V");
if (method1 != 0) {
(*env)->CallVoidMethod(env, dpobj, method1, name);
} else {
LOGE("cant find setName method");
}
jmethodID method2 = (*env)->GetMethodID(env, cls, "setAge", "(I)V");
if (method2 != 0) {
(*env)->CallVoidMethod(env, dpobj, method2, age);
} else {
LOGE("can't find method setAge");
}

return dpobj;
}

/* This function will be call when the library first be load.
* You can do some init in the libray. return which version jni it support.
*/
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
LOGI("dufresne----->JNI_OnLoad!");
return JNI_VERSION_1_4;
}


package com.example.test;

public class TestJava {

//如果是静态方法的话,传递给jni层的jobject为jclass对象,否则就是对象
public static native String speak();

public static native Object getMyClass(int age, String name);

static {
System.loadLibrary("HelloWorldJni");
}

}


android.mk

LOCAL_PATH:= $(call my-dir)
# 一个完整模块编译
include $(CLEAR_VARS)
LOCAL_LDLIBS    := -lm -llog
LOCAL_SRC_FILES:=Hello.c
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_MODULE := libHelloWorldJni
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS :=optional
include $(BUILD_SHARED_LIBRARY)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jni