This commit is contained in:
228
cpp/nativecall/VoidCall.cpp
Normal file
228
cpp/nativecall/VoidCall.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* VoidCall.cpp
|
||||
*
|
||||
* Created on 16.09.2004.
|
||||
*
|
||||
* $Id: VoidCall.cpp,v 1.4 2006/04/20 05:50:15 grnull Exp $
|
||||
*
|
||||
* eaio: NativeCall - calling operating system methods from Java
|
||||
* Copyright (c) 2004-2006 Johann Burkard (<mailto:jb@eaio.com>)
|
||||
* <http://eaio.com>
|
||||
*
|
||||
* 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 <jni.h>
|
||||
#include "com_eaio_nativecall_VoidCall.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#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_VoidCall
|
||||
* Method: executeCall
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_eaio_nativecall_VoidCall_executeCall
|
||||
(JNIEnv *env, jobject obj) {
|
||||
|
||||
jint functionHandle = env->GetIntField(obj, fieldFunctionHandle);
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef _X86_
|
||||
|
||||
__asm {
|
||||
|
||||
call functionHandle
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
env->SetIntField(obj, fieldLastErrorCode, GetLastError());
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: com_eaio_nativecall_VoidCall
|
||||
* Method: executeCall0
|
||||
* Signature: ([Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_eaio_nativecall_VoidCall_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;
|
||||
}
|
||||
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);
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef _X86_
|
||||
|
||||
__asm {
|
||||
|
||||
call functionHandle
|
||||
|
||||
}
|
||||
|
||||
#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());
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user