c - what is wrong with this call to the java method? -
i trying call java method code. c code listens either escape, shift, ctrl key press, calls java method telling key pressed. following snippets play role in this.
c snippet:
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 java method break; case vk_shift: printf("shift pressed !\n"); (*env)->callvoidmethoda(env,obj,mid,"10"); // calling java method break; case vk_escape: printf("escape pressed !\n"); (*env)->callvoidmethoda(env,obj,mid,"1b"); // calling java method break; default: printf("the default case\n"); break; } java snippet:
public void callback(string key) { string x = keyevent.getkeytext(integer.parseint(key, 16)); system.out.println(x); } when run program , press escape key on console:
escape pressed ! # # fatal error has been detected java runtime environment: # # exception_access_violation (0xc0000005) @ 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] # # error report file more information saved as: # w:\undertest\netbeanscurrent\keyloggertester\build\classes\hs_err_pid7588.log # # if submit bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # i know calling java function wrong way, don't know wrong. output, satisfies case when press escape key , unexpected error occurs.
edit:
after answer mavroprovato still same errors.
i edited way:
(*env)->callvoidmethoda(env,obj,mid,(*env)->newstringutf(env,"1b")); edit:
complete code version 1
complete code version 2
the jvm crashing because jnienv used not valid one. there other issues code well.
the sun jni documentation providing information regarding threads.
here comes parts obvious:
create jni_onload function in code. called when library loaded. cache javavm pointer because valid across threads. alternative call (*env)->getjavavm in initializejnivars function prefer first one.
in initializejnivars can save obj reference calling obj = (*env)->newglobalref(obj).
in lowlevelkeyboardproc have env pointer:
attachcurrentthread(javavm *jvm, jnienv &env, null);
edit
ok, here code should add working, have tried myself , works. nb: have not analyzed code doing did fixes working.
add these variables among other global variables:
static javavm *javavm = null; static jmethodid callbackmethod = null; static jobject callbackobject = null; you can remove cls, mid, env , obj variables , use mine instead.
create jni_onload method cache 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; } alter initializejnivars following:
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 null \n"); } called = true; } and in lowloevelkeyboardproc code have add following:
... wparam param = kbhook->vkcode; jnienv *env; jint rs = (*javavm)->attachcurrentthread(javavm, (void**)&env, null); if (rs != jni_ok) { return null; // or appropriate... } ... case vk_escape: printf("escape pressed !\n"); jstring message = (*env)->newstringutf(env, "1b"); (*env)->callvoidmethod(env, callbackobject, callbackmethod, message); break; ... in unregisterwinhook should delete global reference objects can gc'd.
... (*env)->deleteglobalref(env, callbackobject); and that's it.
Comments
Post a Comment