基本信息
源码名称:JAVA JNI 样例,总结了JNI的书写方法。
源码大小:0.08M
文件格式:.gz
开发语言:Java
更新时间:2017-03-10
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 1 元 
   源码介绍


#include <stdio.h>
//#include <jni.h>
#include "src_com_android_camera_TestCameraJni.h"

//本文件中用 Java_包名_类名_函数名 的JNI函数命名法

//要注意c与c 的写法不一样,这是因为 Android 源码中的 native 层的实现使用的是 C ,而我们这里使用的是 C语言

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jstring JNICALL Java_src_com_android_camera_TestCameraJni_testJni(JNIEnv *env,jobject obj,jint age,jstring name);
#ifdef __cplusplus
};
#endif

JNIEXPORT jstring Java_src_com_android_camera_TestCameraJni_nativeFunc(JNIEnv *env, jclass cls, jstring msg)
{
    const char *cmsg;
    char cres[1024];
    jstring res;
    cmsg = (*env)->GetStringUTFChars(env, msg, JNI_FALSE);
    memset(cres, '\0', 1024);
    strcat(cres, cmsg);
    strcat(cres, " (Solved)");
    res = (*env)->NewStringUTF(env, cres);
    (*env)->ReleaseStringUTFChars(env, msg, cmsg);
    return res;
}


JNIEXPORT jstring Java_src_com_android_camera_TestCameraJni_testJni(JNIEnv *env,jobject obj,jint age,jstring name)
{
//const char* pname = env->GetStringUTFChars(name, NULL); //C 的写法
const char* pname = (*env)->GetStringUTFChars(env,name, NULL);     //C的写法

printf("\nhello ,here is the JNICALL testJni: %d name:%s\n\n",age,pname);
#if 1
jclass class_Test = (*env)->GetObjectClass(env,obj); //获取JAVA实例,也就是TestCameraJni类的实例,所以后面的GetFieldID等都是TestCameraJni类的属性
 
//jfieldID fid_a = (*env)->GetFieldID(env,class_Test,"amessage","Ljava/lang/String;"); // TestCameraJni.amessage
//pname = (*env)->GetStringUTFChars(env,fid_a, NULL);
//printf("amessage : %s",fid_a);
//(*env)->SetObjectField(env,obj,fid_a,"2323");

jfieldID fid_b = (*env)->GetFieldID(env,class_Test,"id","I");
(*env)->SetIntField(env,obj,fid_b,12123);

#endif
(*env)->ReleaseStringUTFChars(env,name, NULL); //通知JVM销毁字符串所占空间,与GetStringUTFChars配对使用
return (*env)->NewStringUTF(env,"this is the C code return string !!");
}

#if 0
//char*   、 jstring互转
JNIEXPORT jstring JNICALL Java_com_explorer_jni_SambaTreeNative_getDetailsBy\
(JNIEnv *env, jobject jobj, jstring pc_server, jstring server_user, jstring server_passwd)  
{  
const char *pc = env->GetStringUTFChars(pc_server, NULL);  
const char *user = env->GetStringUTFChars(server_user, NULL);  
const char *passwd = env->GetStringUTFChars(server_passwd, NULL);  
const char *details = smbtree::getPara(pc, user, passwd);  
jstring jDetails = env->NewStringUTF(details);  
return jDetails;  


//char * 转 jstring
jstring WindowsTojstring(JNIEnv* env, char* str_tmp)  
{  
jstring rtn=0;  
int slen = (int)strlen(str_tmp);  
unsigned short* buffer=0;  
if(slen == 0){  
rtn = env->NewStringUTF(str_tmp);  
}  
else{  
int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str_tmp, slen, NULL, 0);  
buffer = (unsigned short*)malloc(length*2 1);  
if(MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str_tmp, slen, (LPWSTR)buffer, length) > 0){  
rtn = env->NewString((jchar*)buffer, length);  
}  
}  
if(buffer){  
free(buffer);  
}  
return rtn;  
}  

//jbyteArray 转 char *                     
char* data = (char*)env->GetByteArrayElements(strIn, 0); 


//C 中的BYTE[]转jbyteArray 
//nOutSize是BYTE数组的长度 BYTE pData[]  
jbyte *by = (jbyte*)pData;  
jbyteArray jarray = env->NewByteArray(nOutSize);  
env->SetByteArrayRegin(jarray, 0, nOutSize, by); 

//jbyteArray 转 c 中的BYTE[] 
    //jbytearray strIn  
    jbyte * olddata = (jbyte*)env->GetByteArrayElements(strIn, 0);  
    jsize  oldsize = env->GetArrayLength(strIn);  
    BYTE* bytearr = (BYTE*)olddata;  
    int len = (int)oldsize;  

#endif


#include <stdio.h>
#include "jni.h"
#include "JNIHelp.h"
#ifdef __cplusplus
extern "C" {
#endif
//本文件中不用 Java_包名_类名_函数名 的JNI函数命名法,而是在JNI_OnLoad时注册本地方法
//JNI_OnLoad在System.loadLibrary()时,JVM会自动调用。

//要注意c与c 的写法不一样,这是因为 Android 源码中的 native 层的实现使用的是 C ,而我们这里使用的是 C语言

jstring testJni(JNIEnv *env,jobject obj,jint age,jstring name)
{
//const char* pname = env->GetStringUTFChars(name, NULL); //C 的写法
const char* pname = (*env)->GetStringUTFChars(env,name, NULL);     //C的写法

printf("\nhello ,here is the JNICALL testJni: %d name:%s\n\n",age,pname);
#if 1
jclass class_Test = (*env)->GetObjectClass(env,obj); //获取JAVA实例,也就是TestCameraJni类的实例,所以后面的GetFieldID等都是TestCameraJni类的属性
 
//jfieldID fid_a = (*env)->GetFieldID(env,class_Test,"amessage","Ljava/lang/String;"); // TestCameraJni.amessage
//pname = (*env)->GetStringUTFChars(env,fid_a, NULL);
//printf("amessage : %s",fid_a);
//(*env)->SetObjectField(env,obj,fid_a,"2323");

jfieldID fid_b = (*env)->GetFieldID(env,class_Test,"id","I");
(*env)->SetIntField(env,obj,fid_b,12123);

#endif
(*env)->ReleaseStringUTFChars(env,name, NULL); //通知JVM销毁字符串所占空间,与GetStringUTFChars配对使用
return (*env)->NewStringUTF(env,"this is the C code return string !!");
}


jstring native_function(JNIEnv *env, jclass cls, jstring msg)
{
    const char *cmsg;
    char cres[1024];
    jstring res;
    cmsg = (*env)->GetStringUTFChars(env, msg, JNI_FALSE);
    memset(cres, '\0', 1024);
    strcat(cres, cmsg);
    strcat(cres, " (Solved)");
    res = (*env)->NewStringUTF(env, cres);
    (*env)->ReleaseStringUTFChars(env, msg, cmsg);
    return res;
}


#ifdef __cplusplus
};
#endif
#if 0
//char*   、 jstring互转
JNIEXPORT jstring JNICALL Java_com_explorer_jni_SambaTreeNative_getDetailsBy\
(JNIEnv *env, jobject jobj, jstring pc_server, jstring server_user, jstring server_passwd)  
{  
const char *pc = env->GetStringUTFChars(pc_server, NULL);  
const char *user = env->GetStringUTFChars(server_user, NULL);  
const char *passwd = env->GetStringUTFChars(server_passwd, NULL);  
const char *details = smbtree::getPara(pc, user, passwd);  
jstring jDetails = env->NewStringUTF(details);  
return jDetails;  


//char * 转 jstring
jstring WindowsTojstring(JNIEnv* env, char* str_tmp)  
{  
jstring rtn=0;  
int slen = (int)strlen(str_tmp);  
unsigned short* buffer=0;  
if(slen == 0){  
rtn = env->NewStringUTF(str_tmp);  
}  
else{  
int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str_tmp, slen, NULL, 0);  
buffer = (unsigned short*)malloc(length*2 1);  
if(MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str_tmp, slen, (LPWSTR)buffer, length) > 0){  
rtn = env->NewString((jchar*)buffer, length);  
}  
}  
if(buffer){  
free(buffer);  
}  
return rtn;  
}  

//jbyteArray 转 char *                     
char* data = (char*)env->GetByteArrayElements(strIn, 0); 


//C 中的BYTE[]转jbyteArray 
//nOutSize是BYTE数组的长度 BYTE pData[]  
jbyte *by = (jbyte*)pData;  
jbyteArray jarray = env->NewByteArray(nOutSize);  
env->SetByteArrayRegin(jarray, 0, nOutSize, by); 

//jbyteArray 转 c 中的BYTE[] 
    //jbytearray strIn  
    jbyte * olddata = (jbyte*)env->GetByteArrayElements(strIn, 0);  
    jsize  oldsize = env->GetArrayLength(strIn);  
    BYTE* bytearr = (BYTE*)olddata;  
    int len = (int)oldsize;  

#endif





//JNI register
////////////////////////////////////////////////////////////////
static const char *classPathName = "src/com/android/camera/TestCameraJni";

// 定义Java本地方法与JNI动态库中方法的映射关系
static JNINativeMethod methods[] = {
  {"testJni", "(ILjava/lang/String;)Ljava/lang/String;", (void*)testJni}, //注意后面的纷号,如果缺少将在注册时出错
  {"nativeFunc", "(Ljava/lang/String;)Ljava/lang/String;", (void *)native_function} //这个可以正常使用
};

/*
 * Register several native methods for one class.
 */
static int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;

    //clazz = env->FindClass(className); //C 的写法
    clazz = (*env)->FindClass(env,className); //C的写法
    if (clazz == NULL) {
  printf("error 3\n");
return JNI_FALSE;
    }

    //if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { //C 的写法
    if ((*env)->RegisterNatives(env,clazz, gMethods, numMethods) < 0) { //C的写法
  printf("error 2\n");
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

/*
 * Register native methods for all classes we know about.
 *
 * returns JNI_TRUE on success.
 */
static int registerNatives(JNIEnv* env)
{
  if (!registerNativeMethods(env, classPathName,methods, sizeof(methods) / sizeof(methods[0]))) {
printf("error 1\n");
    return JNI_FALSE;
  }

  return JNI_TRUE;
}

typedef union {
    JNIEnv* env;
    void* venv;
} UnionJNIEnvToVoid;

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    UnionJNIEnvToVoid uenv;
    uenv.venv = NULL;
    jint result = -1;
    JNIEnv* env = NULL;
    if ((*vm)->GetEnv(vm,&uenv.venv, JNI_VERSION_1_4) != JNI_OK) { //C的写法
    //if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) { //C 的写法
        goto bail;
    }
    env = uenv.env;

    if (registerNatives(env) != JNI_TRUE) {
        goto bail;
    }
    printf("OK\n");
    result = JNI_VERSION_1_4;
    
bail:
    return result;
}