/* * IntCall.cpp * * Created on 11.09.2004. * * $Id: IntCall.cpp,v 1.3 2006/04/19 20:54:55 grnull Exp $ * * eaio: NativeCall - calling operating system methods from Java * Copyright (c) 2004-2006 Johann Burkard () * * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include #include "com_eaio_nativecall_IntCall.h" #ifdef _WINDOWS #include #include #endif #ifdef _WINDOWS #ifdef _X86_ #define _push(x) __asm { push x }; #endif #endif // NativeCall fields extern jfieldID fieldFunction, fieldModule, fieldFunctionHandle, fieldModuleHandle, fieldLastErrorCode; // Holder fields extern jfieldID fieldHolderO; // Classes extern jclass classBoolean,/* classByte, classCharacter, classShort,*/ classInteger, /* classLong, classFloat, classDouble,*/ classString, classByteArray, classCharArray, /*classIntArray,*/ classHolder; // Wrapper class methods extern jmethodID methodBooleanValue,/* methodByteValue, methodCharValue, methodShortValue,*/ methodIntValue/*, methodLongValue, methodFloatValue, methodDoubleValue*/; // Constructors extern jmethodID newIntegerInt, newBooleanBoolean; /* * Class: com_eaio_nativecall_IntCall * Method: executeCall * Signature: ()I */ JNIEXPORT jint JNICALL Java_com_eaio_nativecall_IntCall_executeCall (JNIEnv *env, jobject obj) { jint functionHandle = env->GetIntField(obj, fieldFunctionHandle); jint outVal; #ifdef _WINDOWS #ifdef _X86_ __asm { call functionHandle mov outVal, eax } #endif #endif env->SetIntField(obj, fieldLastErrorCode, GetLastError()); return outVal; } /* * Class: com_eaio_nativecall_IntCall * Method: executeCall0 * Signature: ([Ljava/lang/Object;)I */ JNIEXPORT jint JNICALL Java_com_eaio_nativecall_IntCall_executeCall0 (JNIEnv *env, jobject obj, jobjectArray params) { const int len = env->GetArrayLength(params); int* arrays = NULL; if (!(arrays = new int[len])) { env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), NULL); return 0; } memset(arrays, 0, (sizeof(int) * len)); jobject param; for (int i = len - 1; i >= 0; i--) { param = env->GetObjectArrayElement(params, i); if (param == NULL) { _push(0); } else if (env->IsInstanceOf(param, classInteger)) { int intArg = env->CallIntMethod(param, methodIntValue); _push(intArg) } else if (env->IsInstanceOf(param, classByteArray)) { char* byteArrayArg = (char*) env->GetPrimitiveArrayCritical((jarray) param, 0); arrays[i] = (int) &byteArrayArg; _push(byteArrayArg) } else if (env->IsInstanceOf(param, classCharArray)) { unsigned short* charArrayArg = (unsigned short*) env->GetPrimitiveArrayCritical( (jarray) param, 0); arrays[i] = (int) &charArrayArg; _push(charArrayArg) } else if (env->IsInstanceOf(param, classBoolean)) { jboolean booleanArg = env->CallBooleanMethod(param, methodBooleanValue); int tempArg = (booleanArg == JNI_FALSE ? 0 : 1); _push(tempArg) } else if (env->IsInstanceOf(param, classHolder)) { /* Holder */ jobject o = env->GetObjectField(param, fieldHolderO); if (env->IsInstanceOf(o, classInteger)) { int *intPtr = new int; *intPtr = env->CallIntMethod(o, methodIntValue); arrays[i] = (int) intPtr; _push(intPtr); } else if (env->IsInstanceOf(o, classByteArray)) { char* byteArrayArg = (char*) env->GetPrimitiveArrayCritical((jarray) o, 0); arrays[i] = (int) &byteArrayArg; _push(byteArrayArg) } else if (env->IsInstanceOf(o, classCharArray)) { unsigned short* charArrayArg = (unsigned short*) env->GetPrimitiveArrayCritical( (jarray) o, 0); arrays[i] = (int) &charArrayArg; _push(charArrayArg) } else if (env->IsInstanceOf(o, classBoolean)) { jboolean booleanArg = env->CallBooleanMethod(o, methodBooleanValue); int *tempPtr = new int; *tempPtr = (booleanArg == JNI_FALSE ? 0 : 1); arrays[i] = (int) tempPtr; _push(tempPtr); } /* end Holder */ } } jint functionHandle = env->GetIntField(obj, fieldFunctionHandle); jint outVal; #ifdef _WINDOWS #ifdef _X86_ __asm { call functionHandle mov outVal, eax } #endif #endif for (int j = 0; j < len; ++j) { param = env->GetObjectArrayElement(params, j); if (param == NULL) {} else if (env->IsInstanceOf(param, classByteArray) || env->IsInstanceOf(param, classCharArray)) { env->ReleasePrimitiveArrayCritical((jarray) param, (void*) arrays[j], 0); } else if (env->IsInstanceOf(param, classHolder)) { jobject o = env->GetObjectField(param, fieldHolderO); if (env->IsInstanceOf(o, classInteger)) { int* out = (int*) arrays[j]; env->SetObjectField(param, fieldHolderO, env->NewObject(classInteger, newIntegerInt, *out)); delete out; } else if (env->IsInstanceOf(o, classByteArray) || env->IsInstanceOf(o, classCharArray)) { env->ReleasePrimitiveArrayCritical((jarray) o, (void*) arrays[j], 0); } else if (env->IsInstanceOf(o, classBoolean)) { int* out = (int*) arrays[j]; env->SetObjectField(param, fieldHolderO, env->NewObject(classBoolean, newBooleanBoolean, (*out == 0 ? JNI_FALSE : JNI_TRUE))); delete out; } } } delete [] arrays; env->SetIntField(obj, fieldLastErrorCode, GetLastError()); return outVal; }