最近一直在做JNI的东西, 网上有有多 javah的例子,感觉用这个方式的jni比较死板,不能很好的灵活运用。 不能随便修改包名类名方法名。
研究后发现用JNINativeMethod 对象能够比较方便的添加native方法。
下面是具体代码:
Java code: 只是简单的提供三个native方法。
ComponentCharTool.java
public final class ComponentCharTool {
public static final void loadJniLibrary() {
System.loadLibrary("char_tool_jni");
}
private long nativeContext;
public ComponentCharTool() {
createNativeContext();
}
@Override
protected void finalize() throws Throwable {
deleteNativeContext();
}
private native void createNativeContext();
public native void deleteNativeContext();
public native boolean terminate() throws ScopeException;
public native String getAscii2jis4(String x) throws ScopeException;
}
JNI Coding
//--------------------------------------------------
//define methods
//--------------------------------------------------
namespace {
jclass globalClassRef = NULL;
jfieldID FID_nativeContext = NULL;
//native methods
void JNI_createNativeContext(JNIEnv *env, jobject obj);
void JNI_deleteNativeContext(JNIEnv *env, jobject obj);
jboolean JNI_terminate(JNIEnv *env, jobject obj);
jstring getAscii2jis4(JNIEnv *env, jobject obj, jstring sentence);
}
//--------------------------------------------------
//--------------------------------------------------
bool jni_RegisterNatives(JNIEnv *env) {
if (globalClassRef != NULL) {
return true;
}
jclass clazz = env->FindClass(FEATURECLASS);
if (clazz == NULL) {
return false;
}
if (env->ExceptionCheck() == JNI_TRUE) {
env->DeleteLocalRef(clazz);
return false;
}
FID_nativeContext = env->GetFieldID(clazz, "nativeContext", "J");
JNINativeMethod methods[] = {
{ "createNativeContext", "()V", (void*)JNI_createNativeContext },
{ "deleteNativeContext", "()V", (void*)JNI_deleteNativeContext },
{ "terminate", "()Z", (void*)JNI_terminate },
//(string类型参数)string类型返回值,其中";"是必须的
{ "getAscii2jis4", "(L"JAVA_LANG_STRING";)L"JAVA_LANG_STRING";", (void*)getAscii2jis4 },
};
jint ret = env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0]));
globalClassRef = reinterpret_cast<jclass>(env->NewGlobalRef(clazz));
return (ret == 0);
}
//--------------------------------------------------
// Delete GlobalRef
//--------------------------------------------------
void jni_DeleteGlobalRef(JNIEnv *env) {
env->DeleteGlobalRef(globalClassRef);
}
//--------------------------------------------------
//declaration && define
//--------------------------------------------------
namespace {
//--------------------------------------------------
//create jni flag
//--------------------------------------------------
void JNI_createNativeContext(JNIEnv *env, jobject obj) {
env->SetLongField(obj, FID_nativeContext,1L);
}
//--------------------------------------------------
//--------------------------------------------------
void JNI_deleteNativeContext(JNIEnv *env, jobject obj) {
env->SetLongField(obj, FID_nativeContext, 0L);
}
//--------------------------------------------------
// #terminate()
//--------------------------------------------------
jboolean JNI_terminate(JNIEnv *env, jobject obj) {
jboolean ret = JNI_FALSE;
return ret;
}
jstring getAscii2jis4(JNIEnv *env, jobject obj, jstring sentence){
char* tmpstr = "return string succeeded";
jstring rtstr = env->NewStringUTF(tmpstr);
return rtstr; ;
}
} //End of namespace
//************************
//字符 Java类型 C类型
//V void void
//Z jboolean boolean
//I jint int
//J jlong long
//D jdouble double
//F jfloat float
//B jbyte byte
//C jchar char
//S jshort short
//
//AarryObj start with "["
//
//[I jintArray int[]
//[F jfloatArray float[]
//[B jbyteArray byte[]
//[C jcharArray char[]
//[S jshortArray short[]
//[D jdoubleArray double[]
//[J jlongArray long[]
//[Z jbooleanArray boolean[]