什么是错的这个调用Java方法? [英] what is wrong with this call to the java method?

查看:207
本文介绍了什么是错的这个调用Java方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图调用从code Java方法。 C $ C $ç听为退出控制键preSS,那么它调用Java方法告诉这关键是pressed。以下是在这方面发挥作用的片段。

I am trying to call a Java method from the code. C code listens to either Escape, Shift, Ctrl key press, then it calls the Java method telling which key was pressed. Following are the snippets that play a role in this.

ç段:

mid = (*env)->GetMethodID(env,cls,"callBack","(Ljava/lang/String;)V");
Env = env;
if(called)
    switch(param) {
        case VK_CONTROL:
            printf("Control pressed !\n");
            (*Env)->CallVoidMethodA(Env,Obj,mid,"11"); // calling the java method
            break;
        case VK_SHIFT:
            printf("Shift pressed !\n");
            (*Env)->CallVoidMethodA(Env,Obj,mid,"10"); // calling the java method
            break;
        case VK_ESCAPE:
            printf("Escape pressed !\n");
            (*Env)->CallVoidMethodA(Env,Obj,mid,"1B"); // calling the java method
            break;
        default:
            printf("The default case\n");
            break;
    }

Java代码:

public void callBack(String key) {
    String x = KeyEvent.getKeyText(Integer.parseInt(key, 16));
    System.out.println(x);
}

当我运行PSS的退出键,程序和$ P $我得到这个在控制台上:

When I run the program and press the Escape key I get this on the console:

Escape pressed !
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x5c8b809a, pid=7588, tid=8088
#
# JRE version: 7.0
# Java VM: Java HotSpot(TM) Client VM (20.0-b01 mixed mode, sharing windows-x86 )
# Problematic frame:
# V  [jvm.dll+0x19809a]
#
# An error report file with more information is saved as:
# W:\UnderTest\NetbeansCurrent\KeyLoggerTester\build\classes\hs_err_pid7588.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

我知道我调用Java函数走错路了,但我不知道我错了。从输出,它满足的时候我preSS的情况下,逃生键,然后发生意外错误。

I know I am calling the Java function the wrong way, but I don't know where I am wrong. As from the output, it satisfies the case when I press the Escape key and then an unexpected error occurs.

链接到日志文件

编辑:

mavroprovato 的答案后,我仍然得到同样的错误。

After the answer by mavroprovato I still get the same errors.

我编辑的是这样的:

(*Env)->CallVoidMethodA(Env,Obj,mid,(*Env)->NewStringUTF(Env,"1B"));

编辑:

推荐答案

JVM的崩溃,因为的JNIEnv 时使用不是有效的。没有与code以及其他的问题。

The JVM is crashing because the JNIEnv that is used is not a valid one. There are other issues with the code as well.

借助孙JNI文档是关于提供非常好的信息线程。

The Sun JNI documentation is providing very good information regarding threads.

下面谈到某些部分是显而易见的:

Here comes some parts that are obvious:

创建您的code一 JNI_OnLoad 功能。加载库时它会被调用。然后缓存的JavaVM 指针,因为这是跨线程有效。另一种方法是调用(* ENV) - GT; GetJavaVM initializeJNIVars 的功能,但我preFER的第一个。

Create a JNI_OnLoad function in your code. It will be called when the library is loaded. Then cache the JavaVM pointer because that is valid across threads. An alternative is to call (*env)->GetJavaVM in the initializeJNIVars function but I prefer the first one.

在你的 initializeJNIVars 您可以通过调用保存 OBJ 引用的OBJ =(* ENV) - 方式> NewGlobalRef(OBJ)

In your initializeJNIVars you can save the obj reference by calling Obj = (*env)->NewGlobalRef(obj).

LowLevelKeyboardProc 你必须获得 ENV 指针:

AttachCurrentThread(JavaVM的* JVM,JNIEnv的&安培; ENV,NULL);

修改

OK,这里有code,你应该添加得到它的工作,我已经尝试过了自己和它的作品。 NB :我还没有分析了一下你的code究竟是干什么,所以我只是做了一些修正,以得到它的工作。

OK, here are the code that you should add to get it working, I have tried it myself and it works. NB: I have not analyzed what your code is actually doing so I just did some fixes to get it working.

添加其他的全局变量之间的这些变量:

Add these variables among your other global variables:

static JavaVM *javaVM = NULL;
static jmethodID callbackMethod = NULL;
static jobject callbackObject = NULL;

您可以删除 CLS 中期信封的OBJ 变量,并用我的吧。

You can remove your cls, mid, Env and Obj variables and use mine instead.

创建JNI_OnLoad方法,您缓存的JavaVM指针:

Create the JNI_OnLoad method where you cache the JavaVM pointer:

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
    JNIEnv *env = 0;

    if ((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4)) {
        return JNI_ERR;
    }

    javaVM = jvm;

    return JNI_VERSION_1_4;
}

改变你的 initializeJNIVars 来如下所示:

void Java_keylogger_TestKeys_initializeJNIVars(JNIEnv *env, jobject obj) {
    jclass cls = (*env)->GetObjectClass(env,obj);
    callbackMethod = (*env)->GetMethodID(env, cls, "callBack", "(Ljava/lang/String;)V");
    callbackObject = (*env)->NewGlobalRef(env, obj);
    if(cls == NULL || callbackMethod == NULL) {
        printf("One of them is null \n");
    }
    called = TRUE;
}

终于在你的 LowLoevelKeyboardProc code,你将不得不添加以下内容:

And finally in your LowLoevelKeyboardProc code you will have to add the following:

...
WPARAM param = kbhook->vkCode;

JNIEnv *env;
jint rs = (*javaVM)->AttachCurrentThread(javaVM, (void**)&env, NULL);
if (rs != JNI_OK) {
    return NULL; // Or something appropriate...
}
...

    case VK_ESCAPE:
        printf("Escape pressed !\n");
        jstring message = (*env)->NewStringUTF(env, "1B");
        (*env)->CallVoidMethod(env, callbackObject, callbackMethod, message);
        break;
...

在你的 unregisterWinHook 你应该删除全局引用,以便对象可以GC'd。

In your unregisterWinHook you should delete the global reference so that objects can be GC'd.

...
(*env)->DeleteGlobalRef(env, callbackObject);

这就是它。

这篇关于什么是错的这个调用Java方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆