JNI java c 調用

1:JAVA調用c

public native int callC(String str,float f ,int i,long l,int[]arr);

.c中

#include <jni.h>
#include <string.h>
//打印
#include <android/log.h>
#define LOG_TAG "System.out"
//帶參 宏定義
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

/**
 * JAVA的string 轉    c的str  工具
 */
char* Jstring2CStr(JNIEnv* env, jstring jstr) {
	char* rtn = NULL;
	jclass clsstring = (*env)->FindClass(env, "java/lang/String");
	jstring strencode = (*env)->NewStringUTF(env, "GB2312");
	jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",
			"(Ljava/lang/String;)[B");
	jbyteArray barr = (jbyteArray) (*env)->CallObjectMethod(env, jstr, mid,
			strencode); // String .getByte("GB2312");
	jsize alen = (*env)->GetArrayLength(env, barr);
	jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
	if (alen > 0) {
		rtn = (char*) malloc(alen + 1);         //"\0"
		memcpy(rtn, ba, alen);
		rtn[alen] = 0;
	}
	(*env)->ReleaseByteArrayElements(env, barr, ba, 0);  //
	return rtn;
}

/**
 * jni 工程師 編寫
 */
JNIEXPORT jint JNICALL Java_com_example_jnitest_MainActivity_callC(JNIEnv *env,
		jobject obj, jstring str, jfloat f, jint i, jlong l, jintArray jarray) {
	//string 轉 c
	char *cStr = Jstring2CStr(env, str);
	//c 轉string
	jstring s = (*env)->NewStringUTF(env, cStr);
	//String長度
	int length = (*env)->GetStringLegth(env, str);
	//java int 數組長度
	int size = (*env)->GetArrayLength(env, jarray);
	//數組首地址
	int* cIntArray = (*env)->GetIntArrayElements(env, jarray, 0);
	int var;
	for (var = 0; var < size; ++var) {
		*(cIntArray + i) += 10; 	//修改數組,傳址!
	}
	//jfloat jint 和c一樣
	//jlong 一樣long long
	int result = cFuncation(cStr, f, i, l);
	return result;
}

/**
 *c代碼 c工程師編寫
 */
int cFuncation(char* str, float f, int i, long long l) {
	//printf(""); 使用不了
	LOGD("AAAA"); //打印}
	//業務邏輯...
	return 0 :
}


添加library     -l   library  

LOCAL_LDLIBS+= -llog        //打印庫

   

2:c調用java

反射:

//得到類的字節碼
Class clazz = Test.class.getClassLoader().loadClass("Student");
//解析字節碼 獲取一個方法
Method method = clazz.getMethod("methodName", String.class);
//調用
method.invoke(clazz.newInstance(), "paramString");

javap 獲取參數類型

cd到 bin/classes 下

D:\adt-bundle\workspace\JNITest\bin\classes>javap -s com.example.jnitest.MainActivity

 public void click2(java.lang.String);
   descriptor: (Ljava/lang/String;)V

/**
 *調用java void 參數 String的方法
 */
int cFuncation(JNIEnv *env, jobject obj, char* msg)
{
	//得到類的字節碼
	jclass clazz = (*env)->FindClass(env, "com/example/jnitest/MainActivity");
	if (clazz == 0) {
		LOGD("can't find class");
	} else {
		LOGD("find success");
	}
	//解析字節碼 獲取一個方法
	jmethodID jmethod = (*env)->GetMethodID(env, clazz, "methodName",
			"(Ljava/lang/String;)V");   //V void  I int :return void ,參數 String
	if (jmethod == 0) {
		LOGD("can't find method");
	} else {
		LOGD("find method success");
	}
	//調用<span style="font-family: Arial, Helvetica, sans-serif;">CallVoidMethod     </span>(JNIEnv*, jobject, jmethodID, ...);
	(*env)->CallVoidMethod(env, obj, jmethod, (*env)->NewStringUTF(env, msg));
	return 0;
}


3. c調用靜態的java方法


	public static void methodName()
	{
		System.out.println("java method!");
	}

/**
 *調用java void 參數 void 的   靜態方法
 */
int cFuncation(JNIEnv *env, jobject obj, char* msg)
{
	//得到類的字節碼
	jclass clazz = (*env)->FindClass(env, "com/example/jnitest/MainActivity");
	//解析字節碼 獲取一個方法
	jmethodID jmethod = (*env)->GetStaticMethodID(env, clazz, "methodName", "()V"); //V void
	//調用(JNIEnv*, jobject, jmethodID, ...);
	(*env)->CallStaticVoidMethod(env, clazz, jmethod);
	return 0;
}







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章