示例#1
0
static thread_storage* get_thread_storage(JNIEnv* env) {
  thread_storage* tls = (thread_storage *)TLS_GET(tls_thread_data_key);
  if (tls == NULL) {
    tls = (thread_storage*)malloc(sizeof(thread_storage));
    if (!tls) {
      throwByName(env, EOutOfMemory, "JNA: Can't allocate thread storage");
    }
    else {
      snprintf(tls->name, sizeof(tls->name), "<uninitialized thread name>");
      tls->jvm_thread = JNI_TRUE;
      tls->last_error = 0;
      tls->termination_flag = NULL;
      if ((*env)->GetJavaVM(env, &tls->jvm) != JNI_OK) {
        free(tls);
        throwByName(env, EIllegalState, "JNA: Could not get JavaVM");
        tls = NULL;
      }
      else if (!TLS_SET(tls_thread_data_key, tls)) {
        free(tls);
        throwByName(env, EOutOfMemory, "JNA: Internal TLS error");
        tls = NULL;
      }
    }
  }
  return tls;
}
/*
 * Class:     org_catacombae_catacombae_storage_io_win32_Win32FileStream
 * Method:    write
 * Signature: ([BII[B)V
 */
JNIEXPORT void JNICALL Java_org_catacombae_catacombae_storage_io_win32_Win32FileStream_write(JNIEnv *env, jclass cls, jbyteArray data, jint offset, jint length, jbyteArray handleData) {
    // Microsoft's old-school C compiler forces me to go C90 strict. Hopefully MinGW GCC will be 64-bit soon.
    HANDLE hnd;
    LARGE_INTEGER distance;
    LARGE_INTEGER position;
    BYTE *buffer;
    DWORD bytesWritten = 0;

    //_tprintf(_T("Java_WindowsLowLevelIO_read called\n"));
    if(DEBUG) printf("Java_WritableWin32File_write called\n");

    hnd = getHandle(env, handleData);

    distance.QuadPart = 0;
    if(!SetFilePointerEx(hnd, distance, &position, FILE_CURRENT)) {
        position.QuadPart = 0x7FFFFFFFFFFFFFFFLL;
    }

    buffer = (BYTE*)malloc(length);
    if(!buffer) {
        throwByName(env, "java/lang/RuntimeException",
                    "Error %d (%s) while allocating %d-byte temporary buffer for "
                    "writing.",
                    errno, strerror(errno), length);
        return;
    }

    (*env)->GetByteArrayRegion(env, data, offset, length, buffer); // (jbyteArray)data->(BYTE*)buffer
    //printf("Calling: ReadFile(0x%x, 0x%x, %d, 0x%x, NULL);\n", hnd, buffer, length, &bytesRead);
    if(WriteFile(hnd, buffer, length, &bytesWritten, NULL) == FALSE) {
        //printf("bytesRead: %u\n", (int)bytesRead);
        //printf("GetLastError(): %u\n", (int)GetLastError());
        throwByName(env, "java/lang/RuntimeException",
                    "Error 0x%08X while attempting to write %d bytes to position "
                    "%lld in file (wrote %lu bytes).",
                    GetLastError(), length, (long long) position.QuadPart,
                    (unsigned long) bytesWritten);
        //bytesRead = -1;
    }
    else if(bytesWritten != length)
        throwByName(env, "java/lang/RuntimeException",
                    "Could not write entire buffer to file! Managed to write %lu / "
                    "%d bytes.",
                    (unsigned long) bytesWritten, length);

    free(buffer); // Clean up
}
示例#3
0
/** Store the requested detach state for the current thread. */
void
JNA_detach(JNIEnv* env, jboolean needs_detach, void* termination_flag) {
  thread_storage* tls = get_thread_storage(env);
  if (tls) {
    tls->needs_detach = needs_detach;
    tls->termination_flag = (int *)termination_flag;
    if (needs_detach && tls->jvm_thread) {
      throwByName(env, EIllegalState, "Can not detach from a JVM thread");
    }
  }
}
/* Takes care of parsing the error after a call to MultiByteToWideChar
   as well as converting it to a java exception with an appropriate
   error message. */
void handleMultiByteToWideCharError(JNIEnv *env, DWORD errorCode) {
  char* message;
  DWORD error = GetLastError();
  if(error == ERROR_INSUFFICIENT_BUFFER)
    message = "MultiByteToWideChar says: Insufficient buffer space.";
  else if(error == ERROR_INVALID_FLAGS)
    message = "MultiByteToWideChar says: Invalid flags.";
  else if(error == ERROR_INVALID_PARAMETER)
    message = "MultiByteToWideChar says: Invalid parameters.";
  else if(error == ERROR_NO_UNICODE_TRANSLATION)
    message = "MultiByteToWideChar says: No Unicode translation.";
  else
    message = "Unknown MultiByteToWideChar error!";
  throwByName(env, "java/lang/RuntimeException", message);
}
示例#5
0
callback*
create_callback(JNIEnv* env, jobject obj, jobject method,
                jobjectArray arg_classes, jclass return_class,
                callconv_t calling_convention, 
                jint options,
                jstring encoding) {
  jboolean direct = options & CB_OPTION_DIRECT;
  jboolean in_dll = options & CB_OPTION_IN_DLL;
  callback* cb;
  ffi_abi abi = (calling_convention == CALLCONV_C
		 ? FFI_DEFAULT_ABI : (ffi_abi)calling_convention);
  ffi_abi java_abi = FFI_DEFAULT_ABI;
  ffi_type* return_type;
  ffi_status status;
  jsize argc;
  JavaVM* vm;
  int rtype;
  char msg[MSG_SIZE];
  int i;
  int cvt = 0;
  const char* throw_type = NULL;
  const char* throw_msg = NULL;

  if ((*env)->GetJavaVM(env, &vm) != JNI_OK) {
    throwByName(env, EUnsatisfiedLink, "Couldn't obtain Java VM reference when creating native callback");
    return NULL;
  }
  argc = (*env)->GetArrayLength(env, arg_classes);

  cb = (callback *)malloc(sizeof(callback));
  cb->closure = ffi_closure_alloc(sizeof(ffi_closure), &cb->x_closure);
  cb->saved_x_closure = cb->x_closure;
  cb->object = (*env)->NewWeakGlobalRef(env, obj);
  cb->methodID = (*env)->FromReflectedMethod(env, method);

  cb->vm = vm;
  cb->arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * argc);
  cb->java_arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * (argc + 3));
  cb->arg_jtypes = (char*)malloc(sizeof(char) * argc);
  cb->conversion_flags = (int *)malloc(sizeof(int) * argc);
  cb->rflag = CVT_DEFAULT;
  cb->arg_classes = (jobject*)malloc(sizeof(jobject) * argc);
 
  cb->direct = direct;
  cb->java_arg_types[0] = cb->java_arg_types[1] = cb->java_arg_types[2] = &ffi_type_pointer;
  cb->encoding = newCStringUTF8(env, encoding);

  for (i=0;i < argc;i++) {
    int jtype;
    jclass cls = (*env)->GetObjectArrayElement(env, arg_classes, i);
    if ((cb->conversion_flags[i] = get_conversion_flag(env, cls)) != CVT_DEFAULT) {
      cb->arg_classes[i] = (*env)->NewWeakGlobalRef(env, cls);
      cvt = 1;
    }
    else {
      cb->arg_classes[i] = NULL;
    }

    jtype = get_java_type(env, cls);
    if (jtype == -1) {
      snprintf(msg, sizeof(msg), "Unsupported callback argument at index %d", i);
      throw_type = EIllegalArgument;
      throw_msg = msg;
      goto failure_cleanup;
    }
    cb->arg_jtypes[i] = (char)jtype;
    cb->java_arg_types[i+3] = cb->arg_types[i] = get_ffi_type(env, cls, cb->arg_jtypes[i]);
    if (!cb->java_arg_types[i+3]) {
      goto failure_cleanup;
    }
    if (cb->conversion_flags[i] == CVT_NATIVE_MAPPED
        || cb->conversion_flags[i] == CVT_POINTER_TYPE
        || cb->conversion_flags[i] == CVT_INTEGER_TYPE) {
      jclass ncls;
      ncls = getNativeType(env, cls);
      jtype = get_java_type(env, ncls);
      if (jtype == -1) {
        snprintf(msg, sizeof(msg), "Unsupported NativeMapped callback argument native type at argument %d", i);
        throw_type = EIllegalArgument;
        throw_msg = msg;
        goto failure_cleanup;
      }
      cb->arg_jtypes[i] = (char)jtype;
      cb->java_arg_types[i+3] = &ffi_type_pointer;
      cb->arg_types[i] = get_ffi_type(env, ncls, cb->arg_jtypes[i]);
      if (!cb->arg_types[i]) {
        goto failure_cleanup;
      }
    }

    // Java callback method is called using varargs, so promote floats to 
    // double where appropriate for the platform
    if (cb->arg_types[i]->type == FFI_TYPE_FLOAT) {
      cb->java_arg_types[i+3] = &ffi_type_double;
      cb->conversion_flags[i] = CVT_FLOAT;
      cvt = 1;
    }
    else if (cb->java_arg_types[i+3]->type == FFI_TYPE_STRUCT) {
      // All callback structure arguments are passed as a jobject
      cb->java_arg_types[i+3] = &ffi_type_pointer;
    }
  }
  if (!direct || !cvt) {
    free(cb->conversion_flags);
    cb->conversion_flags = NULL;
    free(cb->arg_classes);
    cb->arg_classes = NULL;
  }
  if (direct) {
    cb->rflag = get_conversion_flag(env, return_class);
    if (cb->rflag == CVT_NATIVE_MAPPED
        || cb->rflag == CVT_INTEGER_TYPE
        || cb->rflag == CVT_POINTER_TYPE) {
      return_class = getNativeType(env, return_class);
    }
  }

#if defined(_WIN32)
  if (calling_convention == CALLCONV_STDCALL) {
#if defined(_WIN64) || defined(_WIN32_WCE)
    // Ignore requests for stdcall on win64/wince
    abi = FFI_DEFAULT_ABI;
#else
    abi = FFI_STDCALL;
    // All JNI entry points on win32 use stdcall
    java_abi = FFI_STDCALL;
#endif
  }
#endif // _WIN32

  if (!(abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) {
    snprintf(msg, sizeof(msg), "Invalid calling convention %d", abi);
    throw_type = EIllegalArgument;
    throw_msg = msg;
    goto failure_cleanup;
  }

  rtype = get_java_type(env, return_class);
  if (rtype == -1) {
    throw_type = EIllegalArgument;
    throw_msg = "Unsupported callback return type";
    goto failure_cleanup;
  }
  return_type = get_ffi_return_type(env, return_class, (char)rtype);
  if (!return_type) {
    throw_type = EIllegalArgument;
    throw_msg = "Error in callback return type";
    goto failure_cleanup;
  }
  status = ffi_prep_cif(&cb->cif, abi, argc, return_type, cb->arg_types);
  if (!ffi_error(env, "callback setup", status)) {
    ffi_type* java_return_type = return_type;

    if (cb->rflag == CVT_STRUCTURE_BYVAL
        || cb->rflag == CVT_NATIVE_MAPPED
        || cb->rflag == CVT_POINTER_TYPE
        || cb->rflag == CVT_INTEGER_TYPE) {
      // Java method returns a jobject, not a struct
      java_return_type = &ffi_type_pointer;
      rtype = '*';
    }
    switch(rtype) {
#define OFFSETOF(ENV,METHOD) ((size_t)((char *)&(*(ENV))->METHOD - (char *)(*(ENV))))
    case 'V': cb->fptr_offset = OFFSETOF(env, CallVoidMethod); break;
    case 'Z': cb->fptr_offset = OFFSETOF(env, CallBooleanMethod); break;
    case 'B': cb->fptr_offset = OFFSETOF(env, CallByteMethod); break;
    case 'S': cb->fptr_offset = OFFSETOF(env, CallShortMethod); break;
    case 'C': cb->fptr_offset = OFFSETOF(env, CallCharMethod); break;
    case 'I': cb->fptr_offset = OFFSETOF(env, CallIntMethod); break;
    case 'J': cb->fptr_offset = OFFSETOF(env, CallLongMethod); break;
    case 'F': cb->fptr_offset = OFFSETOF(env, CallFloatMethod); break;
    case 'D': cb->fptr_offset = OFFSETOF(env, CallDoubleMethod); break;
    default: cb->fptr_offset = OFFSETOF(env, CallObjectMethod); break;
    }
    status = ffi_prep_cif_var(&cb->java_cif, java_abi, 2, argc+3, java_return_type, cb->java_arg_types);
    if (!ffi_error(env, "callback setup (2)", status)) {
      ffi_prep_closure_loc(cb->closure, &cb->cif, dispatch_callback, cb,
                           cb->x_closure);
#ifdef DLL_FPTRS
      // Find an available function pointer and assign it
      if (in_dll) {
        for (i=0;i < DLL_FPTRS;i++) {
          if (fn[i] == NULL) {
            fn[i] = cb->x_closure;
            cb->x_closure = dll_fptrs[i];
            break;
          }
        }
        if (i == DLL_FPTRS) {
          throw_type = EOutOfMemory;
          throw_msg = "No more DLL callback slots available";
          goto failure_cleanup;
        }
      }
#endif
      return cb;
    }
  }

 failure_cleanup:
  free_callback(env, cb);
  if (throw_type) {
    throwByName(env, throw_type, throw_msg);
  }

  return NULL;
}
示例#6
0
jint JNI::main(JNIEnv *env, jobject self, jobjectArray args) {
	assert(_system);

	const int MAX_NARGS = 32;
	int res = -1;

	int argc = env->GetArrayLength(args);
	if (argc > MAX_NARGS) {
		throwByName(env, "java/lang/IllegalArgumentException",
					"too many arguments");
		return 0;
	}

	char *argv[MAX_NARGS];

	// note use in cleanup loop below
	int nargs;

	for (nargs = 0; nargs < argc; ++nargs) {
		jstring arg = (jstring)env->GetObjectArrayElement(args, nargs);

		if (arg == 0) {
			argv[nargs] = 0;
		} else {
			const char *cstr = env->GetStringUTFChars(arg, 0);

			argv[nargs] = const_cast<char *>(cstr);

			// exception already thrown?
			if (cstr == 0)
				goto cleanup;
		}

		env->DeleteLocalRef(arg);
	}

	LOGI("Entering scummvm_main with %d args", argc);

	res = scummvm_main(argc, argv);

	LOGI("scummvm_main exited with code %d", res);

	_system->quit();

cleanup:
	nargs--;

	for (int i = 0; i < nargs; ++i) {
		if (argv[i] == 0)
			continue;

		jstring arg = (jstring)env->GetObjectArrayElement(args, nargs);

		// Exception already thrown?
		if (arg == 0)
			return res;

		env->ReleaseStringUTFChars(arg, argv[i]);
		env->DeleteLocalRef(arg);
	}

	return res;
}
示例#7
0
void JNI::throwRuntimeException(JNIEnv *env, const char *msg) {
	throwByName(env, "java/lang/RuntimeException", msg);
}
示例#8
0
/*
 * Throws java.io.IOException
 */
void throwIOException(JNIEnv *env, const char *msg)
{
    throwByName(env, "java/io/IOException", msg);
}
示例#9
0
/*
 * Throws java.lang.NullPointerException
 */
void throwNullPointerException(JNIEnv *env, const char *msg)
{
    throwByName(env, "java/lang/NullPointerException", msg);
}
/*
 * Common code for Java_org_catacombae_hfsexplorer_win32_WritableWin32File_openNative
 * and Java_org_catacombae_hfsexplorer_win32_WindowsLowLevelIO_openNative.
 */
jbyteArray openWin32File(JNIEnv *env,
			 jstring str,
			 DWORD dwDesiredAccess,
			 DWORD dwShareMode,
			 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
			 DWORD dwCreationDisposition,
			 DWORD dwFlagsAndAttributes,
			 HANDLE hTemplateFile) {
  // Microsoft's old-school C compiler forces me to go C90 strict. Hopefully MinGW GCC will be 64-bit soon.
  jsize utf8FilenameLength;
  const jbyte *utf8Filename;
  int wcFilenameSize;
  WCHAR *wcFilename;
  HANDLE hnd;
  
  if(DEBUG) printf("openWin32File called\n");
  if(str == NULL) { // Must check input, or we can crash the jvm.
    throwByName(env, "java/lang/NullPointerException", "Filename is null.");
    return 0;
  }
  
  /* First, we convert the jstring to a jbyte array with the string encoded
     into UTF-8. */
  utf8FilenameLength = (*env)->GetStringUTFLength(env, str);
  utf8Filename = (*env)->GetStringUTFChars(env, str, NULL);
  if(DEBUG) printf("utf8FilenameLength: %d bytes\n", utf8FilenameLength);

  
  /* Then, we convert the UTF-8 string into windows WCHARs */
  wcFilenameSize = MultiByteToWideChar(CP_UTF8, 0, utf8Filename, utf8FilenameLength, NULL, 0);
  if(wcFilenameSize == 0) {
    handleMultiByteToWideCharError(env, GetLastError());
    (*env)->ReleaseStringUTFChars(env, str, utf8Filename);
    return 0;
  }
  ++wcFilenameSize; // the last WCHAR is the null terminator
  if(DEBUG) printf("wcFilenameSize: %d\n", wcFilenameSize);
  wcFilename = (WCHAR*)malloc(sizeof(WCHAR)*wcFilenameSize);
  if(MultiByteToWideChar(CP_UTF8, 0, utf8Filename, utf8FilenameLength, wcFilename, wcFilenameSize) == 0) {
    handleMultiByteToWideCharError(env, GetLastError());
    (*env)->ReleaseStringUTFChars(env, str, utf8Filename);
    free(wcFilename);
    return 0;
  }
  wcFilename[wcFilenameSize-1] = L'\0'; // Null termination.
  (*env)->ReleaseStringUTFChars(env, str, utf8Filename); // Release allocated resources.
  
  
  /* Perfect. */
  if(DEBUG) printf("Attempting to open \"");
  if(DEBUG) wprintf(L"%s", wcFilename);
  if(DEBUG) printf("\"\n");
  hnd = CreateFileW(wcFilename, dwDesiredAccess, dwShareMode, lpSecurityAttributes, 
		    dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  free(wcFilename); // Done with that one now
  if(hnd == INVALID_HANDLE_VALUE) {
    throwByName(env, "java/lang/RuntimeException", "Could not open file.");
    return 0;
  }
  else {
    return getHandleData(env, hnd);
  }  
}
示例#11
0
文件: callback.c 项目: miho/jna
callback*
create_callback(JNIEnv* env, jobject obj, jobject method,
                jobjectArray param_types, jclass return_type,
                callconv_t calling_convention, jboolean direct) {
  callback* cb;
  ffi_abi abi = FFI_DEFAULT_ABI;
  ffi_abi java_abi = FFI_DEFAULT_ABI;
  ffi_type* ffi_rtype;
  ffi_status status;
  jsize argc;
  JavaVM* vm;
  int rtype;
  char msg[64];
  int i;
  int cvt = 0;
  const char* throw_type = NULL;
  const char* throw_msg = NULL;

  if ((*env)->GetJavaVM(env, &vm) != JNI_OK) {
    throwByName(env, EUnsatisfiedLink, "Can't get Java VM");
    return NULL;
  }
  argc = (*env)->GetArrayLength(env, param_types);

  cb = (callback *)malloc(sizeof(callback));
  cb->closure = ffi_closure_alloc(sizeof(ffi_closure), &cb->x_closure);
  cb->object = (*env)->NewWeakGlobalRef(env, obj);
  cb->methodID = (*env)->FromReflectedMethod(env, method);
  cb->vm = vm;
  cb->arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * argc);
  cb->java_arg_types = (ffi_type**)malloc(sizeof(ffi_type*) * (argc + 3));
  cb->arg_jtypes = (char*)malloc(sizeof(char) * argc);
  cb->flags = (int *)malloc(sizeof(int) * argc);
  cb->rflag = CVT_DEFAULT;
  cb->arg_classes = (jobject*)malloc(sizeof(jobject) * argc);
 
  cb->direct = direct;
  cb->java_arg_types[0] = cb->java_arg_types[1] = cb->java_arg_types[2] = &ffi_type_pointer;

  for (i=0;i < argc;i++) {
    int jtype;
    jclass cls = (*env)->GetObjectArrayElement(env, param_types, i);
    if ((cb->flags[i] = get_conversion_flag(env, cls)) != CVT_DEFAULT) {
      cb->arg_classes[i] = (*env)->NewWeakGlobalRef(env, cls);
      cvt = 1;
    }

    jtype = get_jtype(env, cls);
    if (jtype == -1) {
      snprintf(msg, sizeof(msg), "Unsupported argument at index %d", i);
      throw_type = EIllegalArgument;
      throw_msg = msg;
      goto failure_cleanup;
    }
    cb->arg_jtypes[i] = (char)jtype;
    cb->java_arg_types[i+3] = cb->arg_types[i] = get_ffi_type(env, cls, cb->arg_jtypes[i]);
    if (cb->flags[i] == CVT_NATIVE_MAPPED
        || cb->flags[i] == CVT_POINTER_TYPE
        || cb->flags[i] == CVT_INTEGER_TYPE) {
      jclass ncls;
      ncls = getNativeType(env, cls);
      jtype = get_jtype(env, ncls);
      if (jtype == -1) {
        snprintf(msg, sizeof(msg), "Unsupported NativeMapped argument native type at argument %d", i);
        throw_type = EIllegalArgument;
        throw_msg = msg;
        goto failure_cleanup;
      }
      cb->arg_jtypes[i] = (char)jtype;
      cb->java_arg_types[i+3] = &ffi_type_pointer;
      cb->arg_types[i] = get_ffi_type(env, ncls, cb->arg_jtypes[i]);
    }

    if (cb->arg_types[i]->type == FFI_TYPE_FLOAT) {
      // Java method is varargs, so promote floats to double
      cb->java_arg_types[i+3] = &ffi_type_double;
      cb->flags[i] = CVT_FLOAT;
      cvt = 1;
    }
    else if (cb->java_arg_types[i+3]->type == FFI_TYPE_STRUCT) {
      // All callback structure arguments are passed as a jobject
      cb->java_arg_types[i+3] = &ffi_type_pointer;
    }
  }
  if (!direct || !cvt) {
    free(cb->flags);
    cb->flags = NULL;
    free(cb->arg_classes);
    cb->arg_classes = NULL;
  }
  if (direct) {
    cb->rflag = get_conversion_flag(env, return_type);
    if (cb->rflag == CVT_NATIVE_MAPPED
        || cb->rflag == CVT_INTEGER_TYPE
        || cb->rflag == CVT_POINTER_TYPE) {
      return_type = getNativeType(env, return_type);
    }
  }

#if defined(_WIN32) && !defined(_WIN64)
  if (calling_convention == CALLCONV_STDCALL) {
    abi = FFI_STDCALL;
  }
  java_abi = FFI_STDCALL;
#endif // _WIN32

  rtype = get_jtype(env, return_type);
  if (rtype == -1) {
    throw_type = EIllegalArgument;
    throw_msg = "Unsupported return type";
    goto failure_cleanup;
  }
  ffi_rtype = get_ffi_rtype(env, return_type, (char)rtype);
  if (!ffi_rtype) {
    throw_type = EIllegalArgument;
    throw_msg = "Error in return type";
    goto failure_cleanup;
  }
  status = ffi_prep_cif(&cb->cif, abi, argc, ffi_rtype, cb->arg_types);
  if (!ffi_error(env, "callback setup", status)) {
    ffi_type* java_ffi_rtype = ffi_rtype;

    if (cb->rflag == CVT_STRUCTURE_BYVAL
        || cb->rflag == CVT_NATIVE_MAPPED
        || cb->rflag == CVT_POINTER_TYPE
        || cb->rflag == CVT_INTEGER_TYPE) {
      // Java method returns a jobject, not a struct
      java_ffi_rtype = &ffi_type_pointer;
      rtype = '*';
    }
    switch(rtype) {
    case 'V': cb->fptr = (*env)->CallVoidMethod; break;
    case 'Z': cb->fptr = (*env)->CallBooleanMethod; break;
    case 'B': cb->fptr = (*env)->CallByteMethod; break;
    case 'S': cb->fptr = (*env)->CallShortMethod; break;
    case 'C': cb->fptr = (*env)->CallCharMethod; break;
    case 'I': cb->fptr = (*env)->CallIntMethod; break;
    case 'J': cb->fptr = (*env)->CallLongMethod; break;
    case 'F': cb->fptr = (*env)->CallFloatMethod; break;
    case 'D': cb->fptr = (*env)->CallDoubleMethod; break;
    default: cb->fptr = (*env)->CallObjectMethod; break;
    }
    status = ffi_prep_cif(&cb->java_cif, java_abi, argc+3, java_ffi_rtype, cb->java_arg_types);
    if (!ffi_error(env, "callback setup (2)", status)) {
      ffi_prep_closure_loc(cb->closure, &cb->cif, callback_dispatch, cb,
                           cb->x_closure);
      return cb;
    }
  }

 failure_cleanup:
  free_callback(env, cb);
  if (throw_type) {
    throwByName(env, throw_type, msg);
  }

  return NULL;
}
示例#12
0
/*
 * This function simply throws a PKCS#11RuntimeException with the given
 * string as its message.
 *
 * @param env Used to call JNI funktions and to get the Exception class.
 * @param jmessage The message string of the Exception object.
 */
void throwPKCS11RuntimeException(JNIEnv *env, const char *message)
{
    throwByName(env, CLASS_PKCS11RUNTIMEEXCEPTION, message);
}
示例#13
0
/*
 * Throws java.lang.OutOfMemoryError
 */
void throwOutOfMemoryError(JNIEnv *env, const char *msg)
{
    throwByName(env, "java/lang/OutOfMemoryError", msg);
}