Forum Stats

  • 3,837,916 Users
  • 2,262,307 Discussions
  • 7,900,431 Comments

Discussions

Calling Java method from c

813103
813103 Member Posts: 5
edited Apr 20, 2011 2:19PM in Java Native Interface (JNI)
Hi. THis is my problem:

I want to write applet that draws amplitude of a line-out, meaning it draws what you hear. I have the c++ part that reads samples and stores them in a buffer alredy written and the java part that calculate FFT writen as well. Now when the buffer is full c++ dispatche the event and i grab those samples and now i my problem. How to write function that passes that array to the java class. For clarity.

Java code:
public class applet extends Applet
{
init(){...}
public native void start();
public native void stop();

public void setSamples(byte[] array)  //<-- this is the method that i need to call from c++
}
C++ code:
void fullBuffer(char *array)//<-- this function is run when buffor is filled
{
...
lEnv->CallVoidMethod(class_to_be_called,mid_byteAray,jbyteArray); //<-- this of cousre doesn't work but i need somthing with the same effect
}
Tagged:

Answers

  • 813103
    813103 Member Posts: 5
    OK i figure it out i'm posting the solution for any one who ecounter simmilar problem:

    C++ code:
    JavaVM *g_vm ;
    JNIEnv *localEnv;
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm,void *reserved)
    {
    	g_vm = vm;
    	g_vm->AttachCurrentThread( (void**) &localEnv, NULL);
    	return JNI_VERSION_1_2;
    }
    JNIEXPORT void JNICALL Java_jni_callWave_setClass(JNIEnv *env, jobject obj, jobject classref)//we call this function first to set up global reference to our variable
    {
    	class_to_be_called = env->NewGlobalRef(classref);
    }
    void sendByteArrayToJavaApplet(std::string str)
    {
    	int result = g_vm->GetEnv((void **)&localEnv,JNI_VERSION_1_2);
    	jclass jc = localEnv->GetObjectClass(class_to_be_called);
    	jmethodID mid_bytear; = localEnv->GetMethodID(jc,"setByteArray","([B)V");;
    	localEnv->CallVoidMethod(class_to_be_called,mid_bytear,jByteArray);
    }
  • jschellSomeoneStoleMyAlias
    jschellSomeoneStoleMyAlias Member Posts: 24,877 Gold Badge
    810100 wrote:
    {
    class_to_be_called = env-> NewGlobalRef (classref);
    }
    I don't see anything that suggests that is a good idea.
  • EJP
    EJP Member Posts: 32,920 Gold Crown
    It's a C++callback. It has no JNI context when it executes. It needs a class ref. Classic case for using a global ref.
  • jschellSomeoneStoleMyAlias
    jschellSomeoneStoleMyAlias Member Posts: 24,877 Gold Badge
    edited Apr 18, 2011 3:22PM
    EJP wrote:
    It's a C++callback. It has no JNI context when it executes. It needs a class ref. Classic case for using a global ref.
    Ok.

    I do note however that the OPs method name says in part 'JavaApplet'.

    The Sun VM uses class loaders for Applets. So I would suspect it is possible that problems might arise.

    And one can do a callback without doing that of course.
  • EJP
    EJP Member Posts: 32,920 Gold Crown
    edited Apr 19, 2011 7:34PM
    There's a lot of FUD there and not much in the way of fact. All JVMs use class loaders for all Java applications. He has the class. It is already loaded. And a callback requires either a class reference, if it is static, or an object reference if it isn't, and the context demands that either be held as a GlobalRef.
  • jschellSomeoneStoleMyAlias
    jschellSomeoneStoleMyAlias Member Posts: 24,877 Gold Badge
    EJP wrote:
    There's a lot of FUD there and not much in the way of fact. All JVMs use class loaders for all Java applications.
    In the console VMs that I use the class loaders used by the VM itself are not unloaded while the VM is running.

    Browser applets run in in a VM where the class loader will be unloaded.
    He has the class. It is already loaded. And a callback requires either a class reference, if it is static, or an object reference if it isn't, and the context demands that either be held as a GlobalRef.
    Not sure what you mean.

    A callback requires that one accesses something in java.
    In that context it is no different than any code used in JNI except that one cannot expect that java entity will be passed in via a parameter.

    And in JNI code, callback or not, I can write code to get a class and from that either interact with it or interact with other entities. It doesn't require any parameters to do that.

    And I have done lots of callbacks and there was never a "demand" that it be held as a GlobalRef.

    It certainly is possible as a choice however.
This discussion has been closed.