⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dispatch.cpp

📁 jni java本地接口编程例子原代码,是java调用本地操作系统代码的接口
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * %W% %E% *  * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved. * * See also the LICENSE file in this distribution. *//* * JNI native methods supporting the infrastructure for shared * dispatchers.  Includes native methods for classes CPointer, CFunction, and * CMalloc. *//* * The implementation here is more general than what is described * in the JNI book in handling return types other than "int". You * can, however, define the JNI_BOOK constant to make the * Java_CFunction_callInt implementation exactly the same as what * is described in the JNI book. */#ifdef SOLARIS2#include <dlfcn.h>#define LOAD_LIBRARY(name) dlopen(name, RTLD_LAZY)#define FIND_ENTRY(lib, name) dlsym(lib, name)#endif#ifdef WIN32#include <windows.h>#define LOAD_LIBRARY(name) LoadLibrary(name)#define FIND_ENTRY(lib, name) GetProcAddress(lib, name)#endif#include <stdlib.h>#include <string.h>#include <jni.h>#include "CPointer.h"#include "CFunction.h"#include "CMalloc.h"/* Global references to frequently used classes and objects */static jclass Class_String;static jclass Class_Integer;static jclass Class_Float;static jclass Class_Double;static jclass Class_CPointer;/* Cached field and method IDs */static jmethodID MID_String_getBytes;static jmethodID MID_String_init;static jfieldID FID_Integer_value;static jfieldID FID_Float_value;static jfieldID FID_Double_value;static jfieldID FID_CPointer_peer;static jfieldID FID_CFunction_conv;/* Forward declarations */static void JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg);static char * JNU_GetStringNativeChars(JNIEnv *env, jstring jstr);static jstring JNU_NewStringNative(JNIEnv *env, const char *str);static jobject makeCPointer(JNIEnv *env, void *p);/********************************************************************//*		     Native methods of class CFunction		    *//********************************************************************//* These are the set of types CFunction can handle now */typedef enum {    TY_CPTR = 0,    TY_INTEGER,    TY_FLOAT,    TY_DOUBLE,    TY_DOUBLE2,    TY_STRING} ty_t;/* represent a machine word */typedef union {    jint i;    jfloat f;    void *p;} word_t;/* A CPU-dependent assembly routine that passes the arguments to C * stack and invoke the function. */extern "C" void asm_dispatch(void *func,	     int nwords,	     char *args_types,	     word_t *args,	     ty_t res_type,	     word_t *resP,	     int conv);/* invoke the real native function */static voiddispatch(JNIEnv *env,	 jobject self,	 jobjectArray arr,	 ty_t res_ty,	 jvalue *resP){#define MAX_NARGS 32    int i, nargs, nwords;    void *func;    char argTypes[MAX_NARGS];    word_t c_args[MAX_NARGS * 2];    int conv;    nargs = env->GetArrayLength(arr);    if (nargs > MAX_NARGS) {        JNU_ThrowByName(env, "java/lang/IllegalArgumentException",		    "too many arguments");	return;    }    func = (void *)env->GetLongField(self, FID_CPointer_peer);    for (nwords = 0, i = 0; i < nargs; i++) {        jobject arg = env->GetObjectArrayElement(arr, i);	if (arg == NULL) {	    c_args[nwords].p = NULL;	    argTypes[nwords++] = TY_CPTR;	} else if (env->IsInstanceOf(arg, Class_Integer)) {	    c_args[nwords].i =	        env->GetIntField(arg, FID_Integer_value);	    argTypes[nwords++] = TY_INTEGER;	} else if (env->IsInstanceOf(arg, Class_CPointer)) {	    c_args[nwords].p = 	        (void *)env->GetLongField(arg, FID_CPointer_peer);	    argTypes[nwords++] = TY_CPTR;	} else if (env->IsInstanceOf(arg, Class_String)) {	    if ((c_args[nwords].p = JNU_GetStringNativeChars(env, (jstring)arg)) == 0) {	        goto cleanup;	    }	    argTypes[nwords++] = TY_STRING;	} else if (env->IsInstanceOf(arg, Class_Float)) {	    c_args[nwords].f =	        env->GetFloatField(arg, FID_Float_value);	    argTypes[nwords++] = TY_FLOAT;	} else if (env->IsInstanceOf(arg, Class_Double)) {	    *(jdouble *)(c_args + nwords) = 	        env->GetDoubleField(arg, FID_Double_value);	    argTypes[nwords] = TY_DOUBLE;	    /* harmless with 64-bit machines*/	    argTypes[nwords + 1] = TY_DOUBLE2;	    /* make sure things work on 64-bit machines */	    nwords += sizeof(jdouble) / sizeof(word_t);	} else {	    JNU_ThrowByName(env, "java/lang/IllegalArgumentException",			"unrecognized argument type");	    goto cleanup;	}	env->DeleteLocalRef(arg);    }    conv = env->GetIntField(self, FID_CFunction_conv);    asm_dispatch(func, nwords, argTypes, c_args, res_ty, (word_t *)resP, conv);cleanup:    for (i = 0; i < nwords; i++) {        if (argTypes[i] == TY_STRING) {	    free(c_args[i].p);	}    }    return;}/* * Class:     CFunction * Method:    initIDs * Signature: ()V */JNIEXPORT void JNICALL Java_CFunction_initIDs(JNIEnv *env, jclass cls){    FID_CFunction_conv = env->GetFieldID(cls, "conv", "I");}/* * Class:     CFunction * Method:    callCPointer * Signature: ([Ljava/lang/Object;)LCPointer; */JNIEXPORT jobject JNICALL Java_CFunction_callCPointer(JNIEnv *env, jobject self, jobjectArray arr){    jvalue result;    dispatch(env, self, arr, TY_CPTR, &result);    if (env->ExceptionOccurred()) {        return NULL;    }    return makeCPointer(env, (void *)result.j);}/* * Class:     CFunction * Method:    callDouble * Signature: ([Ljava/lang/Object;)D */JNIEXPORT jdouble JNICALL Java_CFunction_callDouble(JNIEnv *env, jobject self, jobjectArray arr){    jvalue result;    dispatch(env, self, arr, TY_DOUBLE, &result);    return result.d;}/* * Class:     CFunction * Method:    callFloat * Signature: ([Ljava/lang/Object;)F */JNIEXPORT jfloat JNICALLJava_CFunction_callFloat(JNIEnv *env, jobject self, jobjectArray arr){    jvalue result;    dispatch(env, self, arr, TY_FLOAT, &result);    return result.f;}#ifdef JNI_BOOKextern "C" int asm_dispatch_int(void *func,                     int nwords,                     word_t *args,                     int conv);     JNIEXPORT jint JNICALL Java_CFunction_callInt  (JNIEnv *env, jobject self, jobjectArray arr){#define MAX_NARGS 32    jint ires;    int nargs, nwords;    void *func;    jboolean is_string[MAX_NARGS];    word_t args[MAX_NARGS];    int conv;    nargs = env->GetArrayLength(arr);    if (nargs > MAX_NARGS) {        JNU_ThrowByName(env,                     "java/lang/IllegalArgumentException",                    "too many arguments");        return 0;    }    // convert arguments    for (nwords = 0; nwords < nargs; nwords++) {        is_string[nwords] = JNI_FALSE;        jobject arg = env->GetObjectArrayElement(arr, nwords);        if (arg == NULL) {            args[nwords].p = NULL;        } else if (env->IsInstanceOf(arg, Class_Integer)) {            args[nwords].i =                env->GetIntField(arg, FID_Integer_value);        } else if (env->IsInstanceOf(arg, Class_Float)) {            args[nwords].f =                env->GetFloatField(arg, FID_Float_value);        } else if (env->IsInstanceOf(arg, Class_CPointer)) {            args[nwords].p = (void *)                env->GetLongField(arg, FID_CPointer_peer);        } else if (env->IsInstanceOf(arg, Class_String)) {            char * cstr = JNU_GetStringNativeChars(env, (jstring)arg);            if ((args[nwords].p = cstr) == NULL) {                goto cleanup; // error thrown            }            is_string[nwords] = JNI_TRUE;        } else {            JNU_ThrowByName(env,                "java/lang/IllegalArgumentException",                "unrecognized argument type");            goto cleanup;        }        env->DeleteLocalRef(arg);    }    func = (void *)env->GetLongField(self, FID_CPointer_peer);    conv = env->GetIntField(self, FID_CFunction_conv);    // now transfer control to func.    ires = asm_dispatch_int(func, nwords, args, conv);cleanup:    // free all the native strings we have created    for (int i = 0; i < nwords; i++) {        if (is_string[i]) {            free(args[i].p);        }    }    return ires;}#else /* JNI_BOOK */JNIEXPORT jint JNICALLJava_CFunction_callInt(JNIEnv *env, jobject self, jobjectArray arr){    jvalue result;    dispatch(env, self, arr, TY_INTEGER, &result);    return result.i;}#endif /* JNI_BOOK *//* * Class:     CFunction * Method:    callVoid * Signature: ([Ljava/lang/Object;)V */JNIEXPORT void JNICALLJava_CFunction_callVoid(JNIEnv *env, jobject self, jobjectArray arr){    jvalue result;    dispatch(env, self, arr, TY_INTEGER, &result);}/* * Class:     CFunction * Method:    find * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J */JNIEXPORT jlong JNICALL Java_CFunction_find  (JNIEnv *env, jobject self, jstring lib, jstring fun){    void *handle;    void *func;    char *libname;    char *funname;    if ((libname = JNU_GetStringNativeChars(env, lib))) {        if ((funname = JNU_GetStringNativeChars(env, fun))) {            if ((handle = (void *)LOAD_LIBRARY(libname))) {                if (!(func = (void *)FIND_ENTRY(handle, funname))) {                    JNU_ThrowByName(env,                         "java/lang/UnsatisfiedLinkError",                        funname);                }            } else {                JNU_ThrowByName(env,                         "java/lang/UnsatisfiedLinkError",                        libname);            }            free(funname);        }        free(libname);    }    return (jlong)func;}/********************************************************************//*		     Native methods of class CPointer		    *//********************************************************************//* * Class:     CPointer * Method:    initIDs * Signature: ()I */JNIEXPORT jint JNICALL Java_CPointer_initIDs(JNIEnv *env, jclass cls){    Class_String = env->FindClass("java/lang/String");    if (Class_String == NULL) return 0;    Class_String = (jclass)env->NewGlobalRef(Class_String);    if (Class_String == NULL) return 0;    Class_Integer = env->FindClass("java/lang/Integer");    if (Class_Integer == NULL) return 0;    Class_Integer = (jclass)env->NewGlobalRef(Class_Integer);    if (Class_Integer == NULL) return 0;    Class_Float = env->FindClass("java/lang/Float");    if (Class_Float == NULL) return 0;    Class_Float = (jclass)env->NewGlobalRef(Class_Float);    if (Class_Float == NULL) return 0;    Class_Double = env->FindClass("java/lang/Double");    if (Class_Double == NULL) return 0;    Class_Double = (jclass)env->NewGlobalRef(Class_Double);    if (Class_Double == NULL) return 0;    Class_CPointer = (jclass)env->NewGlobalRef(cls);    if (Class_CPointer == NULL) return 0;    MID_String_getBytes =         env->GetMethodID(Class_String, "getBytes", "()[B");    if (MID_String_getBytes == NULL) return 0;    MID_String_init = env->GetMethodID(Class_String, "<init>", "([B)V");    if (MID_String_init == NULL) return 0;    FID_Integer_value = env->GetFieldID(Class_Integer, "value", "I");    if (FID_Integer_value == NULL) return 0;    FID_Float_value = env->GetFieldID(Class_Float, "value", "F");    if (FID_Float_value == NULL) return 0;    FID_Double_value = env->GetFieldID(Class_Double, "value", "D");    if (FID_Double_value == NULL) return 0;    FID_CPointer_peer = env->GetFieldID(Class_CPointer, "peer", "J");    return sizeof(void *);}/* * Class:     CPointer * Method:    copyIn * Signature: (I[BII)V */JNIEXPORT void JNICALL Java_CPointer_copyIn__I_3BII  (JNIEnv *env, jobject self, jint boff, jbyteArray arr, jint off, jint n){    jbyte *peer = (jbyte *)env->GetLongField(self, FID_CPointer_peer);    env->GetByteArrayRegion(arr, off, n, peer + boff);}/* * Class:     CPointer * Method:    copyIn * Signature: (I[CII)V */JNIEXPORT void JNICALL Java_CPointer_copyIn__I_3CII  (JNIEnv *env, jobject self, jint boff, jcharArray arr, jint off, jint n){    jchar *peer = (jchar *)env->GetLongField(self, FID_CPointer_peer);    env->GetCharArrayRegion(arr, off, n, peer + boff);}/* * Class:     CPointer * Method:    copyIn * Signature: (I[DII)V */JNIEXPORT void JNICALL Java_CPointer_copyIn__I_3DII  (JNIEnv *env, jobject self, jint boff, jdoubleArray arr, jint off, jint n){    jdouble *peer = (jdouble *)        env->GetLongField(self, FID_CPointer_peer);    env->GetDoubleArrayRegion(arr, off, n, peer + boff);}/* * Class:     CPointer * Method:    copyIn * Signature: (I[FII)V */JNIEXPORT void JNICALL Java_CPointer_copyIn__I_3FII

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -