Is my JNI method OK?

B

bart59

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
 
G

Gordon Beaton

-> 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
 
B

bart59

Thanks for helping me Gordon !
For example, I wonder what happens here:


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?
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.
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:

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
 
B

bart59

Okay, visibly it comes from this point:
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 !
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,981
Messages
2,570,187
Members
46,730
Latest member
AudryNolan

Latest Threads

Top