This discussion is archived
2 Replies Latest reply: Oct 26, 2012 9:45 AM by 970701 RSS

Help with Java and C++/C

970701 Newbie
Currently Being Moderated
Hey guys,

So I'm having some trouble with my code. It works, but not in the way I want it to work. Here is the scenario:

A user clicks (CTRL+1). My C-code will register this sequence and pass a variable to a Java method. [Note: I needed to use C here since my program is designed to run while a full-screen game is running as well. Java would not be able to register the key-events without focus.] The Java method will start a new Thread which will count down. Once a certain amount of time has elapsed, the Java Thread will play a sound clip to the user.

This all works. The problem is, I want to be able to start multiple Threads (not at the same time, though). So, while one Thread could be counting down, another one or two or three could also be counting down. I can get one thread to start, but no new threads will start until the first one is complete. In fact, no key sequences are even registered once a Thread has been started. Following is the C code and partial Java code.

main.cpp
#include <iostream> 
#include <stdio.h>
using namespace std;
#include <windows.h> 
#include <winuser.h> 
#include "startJava.h"

void Stealth();

int main() {
    createJava();
    Stealth();
    int i;
    const char* str;
    int state = 0;

    while (1) {
        for (i = 8; i <= 190; i++) {
            //Key has been pressed
            if (GetAsyncKeyState(i) == -32767) {
                cout << "KEY CODE: " << i << " | CURRENT STATE: " << state << endl;
                if(state == 0 && (i == VK_CONTROL || i == 162)) {
                    state++;
                } else if(state == 1) {
                     ....
                    }
                    if(str == NULL) {
                        break;
                    } else {
                        startJava(str);
                    }
                    state = 0;
                } else {
                    state = 0;
                }
            }
        }
    }
    system("PAUSE");
    return 0;
}
startJava.c
#include "startJava.h"
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <windows.h>

#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */
#define USER_CLASSPATH ...

jint res;
JavaVM *jvm;
JNIEnv* env;

void createJava() {
    
#ifdef JNI_VERSION_1_2
    // definitions required to get the proc address
    HINSTANCE hVM;
    typedef jint(CALLBACK * fpCJV)(JavaVM**, void**, JavaVMInitArgs*);

    fpCJV CreateJavaVM;
    JavaVMInitArgs vm_args;
    JavaVMOption options[1];
    options[0].optionString =
            "-Djava.class.path="  USER_CLASSPATH;
    vm_args.version = 0x00010002;
    vm_args.options = options;
    vm_args.nOptions = 1;
    vm_args.ignoreUnrecognized = JNI_TRUE;
    /* Create the Java VM */
    // load the Java VM dll
    hVM = LoadLibrary("C:\\Program Files (x86)\\Java\\jre7\\bin\\client\\jvm.dll");
    if (hVM == NULL) {
        fprintf(stderr, "Error Loading Library\n");
        exit(1);
    }
    // get the address of the first JNI call and create the VM
    CreateJavaVM = (fpCJV) GetProcAddress(hVM, "JNI_CreateJavaVM");
    res = CreateJavaVM(&jvm, (void**) &env, &vm_args);
    
    if (res < 0) {
        fprintf(stderr, "Can't create Java VM\n");
        exit(1);
    }
#endif /* JNI_VERSION_1_2 */
}

void startJava(const char* str) {
    
    jclass cls;
    jmethodID mid;
    jstring jstr;

    //find class
    ....

    //find method
    ....

    //call method "startTimer"
    mid = (*env)->GetStaticMethodID(env, cls, "startTimer", "(Ljava/lang/String;Z)V");
    if (mid != 0) {
        jstr = (*env)->NewStringUTF(env, str);
        if(jstr != NULL) {
            (*env)->CallStaticVoidMethod(env, cls, mid, jstr, 0);
        }
    }
}
Timer.java (starts new thread)
public static void startTimer(String sType, boolean isEnemy) {
        TimerType type = getType(sType);
        TimerThread tt = new TimerThread(type, isEnemy);
        //tt.isPlayable checks that the .wav file was found
        if(tt.isPlayable()) {
            Thread t = new Thread(tt);
            t.start();
            try {
                t.join();
            } catch(InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }
**EDIT**
Here's the actual run()
@Override
    public void run() {
        try {
            for(int i = 0; i <= (endTime - LAG); i++) {
                if(i%10 == 0) {
                    Logging.log("Thread [" + name + "] is running...\t" + i);
                }
                Thread.currentThread().sleep(Utils.MILLIS_IN_SECOND);
            }
        } catch (InterruptedException ie) {
            return;
        }
        
        try {
            notify.playSound();
        } catch (IOException | UnsupportedAudioFileException | LineUnavailableException ex) {
            Logging.log("Playing sound for " + name + " resulted in error: " + ex);
        }
    }
Edited by: 967698 on Oct 25, 2012 9:05 AM

Edited by: 967698 on Oct 25, 2012 9:11 AM
  • 1. Re: Help with Java and C++/C
    800381 Explorer
    Currently Being Moderated
    Your startTimer() method blocks waiting for the thread you started to finish:
    public static void startTimer(String sType, boolean isEnemy) {
            TimerType type = getType(sType);
            TimerThread tt = new TimerThread(type, isEnemy);
            //tt.isPlayable checks that the .wav file was found
            if(tt.isPlayable()) {
                Thread t = new Thread(tt);
                t.start();
                try {
                    t.join();   <------------------  Waits here for thread to finish
                } catch(InterruptedException ie) {
                    ie.printStackTrace();
                }
            }
        }
  • 2. Re: Help with Java and C++/C
    970701 Newbie
    Currently Being Moderated
    Haha, I didn't even think of that. I actually ended up using AttachThread and DettachThread, which worked just the same.

    Thanks, though!

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points