Is my JNI method OK?

Discussion in 'Java' started by bart59, Jun 11, 2004.

  1. bart59

    bart59 Guest

    Hello,

    I am using JNI,

    I've got for exemple a first JNI function called to initiate the dll.
    It returns the pointer to the mainClass, so that the JNI CallBack loop
    Function can call it:

    /** Create the MainInterface and initalise the h323 connection
    return the MainInterface Pointer to reuse it later in other JNI
    functions**/

    JNIEXPORT jint JNICALL
    Java_ca_sess_voicesess_terminal_JNIWrapper_create
    (JNIEnv *env, jobject obj,jstring options)
    {
    //get the options as a PString
    const char* option = env->GetStringUTFChars(options,NULL);
    PString poptions = option;

    //makes an instance of PProc()
    PProc* g_PProcess = new PProc();

    //make an instance of an endpoint
    MainInterface * mainInterface;
    mainInterface = new MainInterface( env, obj, poptions );
    env->ReleaseStringUTFChars(options,option);

    return ( ( jint ) mainInterface );
    }


    /**
    *CallBack loop, to Get the message ( fifo pile )
    **/

    JNIEXPORT jstring JNICALL
    Java_ca_sess_voicesess_terminal_JNIWrapper_getMsgQueue
    (JNIEnv *env, jobject obj,jint mainInterfacePtr){

    enum CallMode {
    IdleCallMode,
    MakingCallMode,
    HangingUpMode,
    IncomingCallWait,
    IncomingLineCall,
    Active323CallMode,
    ActiveLineCallMode,
    NoGatekeeperMode,
    ApplicationShuttingDown,
    IncomingCallIntrusion
    };

    MainInterface* myMainInterface =
    (MainInterface*)mainInterfacePtr;
    PString * queuePtr = new PString();
    queuePtr = (*myMainInterface).GetMsgFromQueue();

    while((queuePtr==NULL) &&
    !((*myMainInterface).GetCallMode()==ApplicationShuttingDown)){

    queuePtr = ((*myMainInterface).GetMsgFromQueue());
    #ifdef _WIN32
    Sleep(1000);
    #endif
    #ifndef _WIN32
    sleep(1);
    #endif
    }

    if(((*myMainInterface).GetCallMode()!=ApplicationShuttingDown)){
    (*myMainInterface).ShowOutputs("Return OK, trying to display the
    pointer data");
    (*myMainInterface).ShowOutputs(PString("FIFO Msg:") + queuePtr[0]);

    return env->NewStringUTF(queuePtr[0]);
    }

    else {
    return env->NewStringUTF("1end");
    }


    By the waym I don know if it is the best method to have a callback
    from the dll:
    is there better method, faster/more secure?
    -> Today I've got a PROBLEM with my program: sometimes it's freezing
    all the java side (but the dll is still working...), doesn't seem to
    be a problem from swing (I use InvokeLater etc...), nor from the dll,
    because it is still runnning, however, if I don't use the callBack JNI
    function from Java, the problem seems to stop (it is difficult to
    evaluate because it occurs only sometimes, it is not systematic...)

    Thanks for your help !

    Bart
    bart59, Jun 11, 2004
    #1
    1. Advertising

  2. > -> Today I've got a PROBLEM with my program: sometimes it's freezing
    > all the java side (but the dll is still working...), doesn't seem to
    > be a problem from swing (I use InvokeLater etc...), nor from the
    > dll, because it is still runnning, however, if I don't use the
    > callBack JNI function from Java, the problem seems to stop (it is
    > difficult to evaluate because it occurs only sometimes, it is not
    > systematic...)


    There is nothing blatantly wrong with the code you've posted, but
    there are some things that look strange to me.

    For example, I wonder what happens here:

    > mainInterface = new MainInterface( env, obj, poptions );


    What does the MainInterface constructor do with env and obj? You can't
    safely use env or obj in any other context than the current one (so
    don't attempt to save them for use later). If you need to store obj
    for later, create a global reference (NewGlobalRef()) for it and store
    *that*. If you need to use env in a different context (i.e. from a
    different thread, or inside a different native call), then use one
    created specifically for that context or use AttachCurrentThread().

    What happens to poptions in the constructor? Do you save the pointer,
    or create a copy of the string contents? The pointer and contents are
    no longer valid after the call to ReleaseStringUTFChars().

    > PProc* g_PProcess = new PProc();


    Why do you create this object here? You don't refer to it again, and
    the pointer goes out of scope when the native method returns. Doesn't
    this cause a memory leak in your application?

    > PString * queuePtr = new PString();


    What happens to the PString() you've just created? When is it freed?
    Isn't this another memory leak? You overwrite the pointer anyway with
    the next call:

    > queuePtr = (*myMainInterface).GetMsgFromQueue();


    > By the waym I don know if it is the best method to have a callback
    > from the dll: is there better method, faster/more secure?


    There's nothing inherently wrong with using a callback or storing a
    pointer to the object in the java class like you've done, although I'd
    use a long, not an int.

    And since we've got no idea what you actually do in your code, it's
    hard to suggest a "better" way to do it. Why don't you think this is a
    good way of solving your problem? What do you mean by "more secure"?

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
    Gordon Beaton, Jun 11, 2004
    #2
    1. Advertising

  3. bart59

    bart59 Guest

    Thanks for helping me Gordon !

    > For example, I wonder what happens here:
    >
    > > mainInterface = new MainInterface( env, obj, poptions );

    >
    > What does the MainInterface constructor do with env and obj? You can't
    > safely use env or obj in any other context than the current one (so
    > don't attempt to save them for use later). If you need to store obj
    > for later, create a global reference (NewGlobalRef()) for it and store
    > *that*. If you need to use env in a different context (i.e. from a
    > different thread, or inside a different native call), then use one
    > created specifically for that context or use AttachCurrentThread().


    Actually, I don t need env and obj (it was a rest from a previous
    version), sorry for that ...

    > What happens to poptions in the constructor? Do you save the pointer,
    > or create a copy of the string contents? The pointer and contents are
    > no longer valid after the call to ReleaseStringUTFChars().
    >


    Here is what I do:

    PConfig config;
    // Get some parameters, saving them to a PStringArray
    //format: label1=value1;label2=value2;...
    PStringArray optionsArray = poptions.Tokenise( ";", TRUE );
    //save this data to a config instance, creating needed fields
    //format: label=paramter
    for(int i=0;i<optionsArray.GetSize();i++){
    PStringArray currentOption=optionsArray.Tokenise( "=", TRUE );
    if(currentOption.GetSize()==2){
    //OK, correct size, we can save the option to the config.
    config.SetString(currentOption[0],currentOption[1]);
    }
    }
    I am not shure if I PConfig.SetString is making a copy of the strings
    or is
    saving the pointer reference... i'll try to find it out.
    What is a secure methode to make a "copy" on a String ? I should use a
    copyConstructor?

    > > PProc* g_PProcess = new PProc();

    >
    > Why do you create this object here? You don't refer to it again, and
    > the pointer goes out of scope when the native method returns. Doesn't
    > this cause a memory leak in your application?


    That sound to be a probleme... Actually I need to create an instance
    of PProc() to be able to create MainInterface(), that's needed by the
    PWlib I think.
    I will try to clean the way I do that.

    >
    > > PString * queuePtr = new PString();

    >
    > What happens to the PString() you've just created? When is it freed?
    > Isn't this another memory leak? You overwrite the pointer anyway with
    > the next call:
    >
    > > queuePtr = (*myMainInterface).GetMsgFromQueue();

    >


    OK, it's a problem to overwrite a pointer ? I should first freed it ?
    -> and of course free at the end of the methode if I dont use it
    anymore.

    My program is a GUI for openh323, an VoIP library.

    I still got a strange problem:
    under Linux, if I use the JNI, after a while the GUI is freezing ...
    What is strange is that it freeze also if I remove any call back: so
    the JNI connection is just made at the beginning, initialisating the
    h323lib and connecting to another client -> no problem. Butafter a
    while Java side is frozen, but at the same time the JNI side, is still
    running and responding: it intercept hang up from other party, etc...

    AS there is no visible link between the library and the guy after the
    initialisation, I cant understand why the GUI is freezing because of
    JNI (if I remove JNI initialisation, there is no problem)

    Thanks for you help !

    Bart
    bart59, Jun 15, 2004
    #3
  4. bart59

    bart59 Guest

    Okay, visibly it comes from this point:
    >
    > > PProc* g_PProcess = new PProc();


    If I remove everything in the JNI function, exept this line,
    then it cause a probleme (java freezing), otherwise, no problem.

    This declaration is necessary to use PWLib later in the program.

    Instanciating it after in mainInterface is may be a better solution !

    I'll try it !
    bart59, Jun 15, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jabel D. Morales - VMan of Mana

    Problems with JNI: calling a Java method from native method.

    Jabel D. Morales - VMan of Mana, Aug 1, 2003, in forum: Java
    Replies:
    1
    Views:
    4,742
    Joseph Millar
    Aug 1, 2003
  2. Alex Hunsley

    IBM's JNI fails where Sun's JNI works

    Alex Hunsley, Nov 3, 2003, in forum: Java
    Replies:
    4
    Views:
    837
    Alex Hunsley
    Nov 4, 2003
  3. Pasturel Jean-Louis

    Porting JNI Windows under JNI LINUX + Wine ?

    Pasturel Jean-Louis, Feb 29, 2004, in forum: Java
    Replies:
    5
    Views:
    892
    Pasturel Jean-Louis
    Mar 3, 2004
  4. vasanth
    Replies:
    0
    Views:
    2,663
    vasanth
    Jan 25, 2005
  5. vasanth
    Replies:
    0
    Views:
    610
    vasanth
    Jan 25, 2005
Loading...

Share This Page