On 16 Apr., 19:22, Gordon Beaton <n...@for.email> wrote:
> On 16 Apr 2007 09:57:06 -0700, Daniel.Boegel...@gmx.de wrote:
>
> > continueListening = (*env)->CallBooleanMethod(env, prxParams.jobj,
> > jmid, jStr);
>
> So, how can you be certain that the code you've posted actually
> contains the error?
>
> Since the actual String creation and method call don't appear to be
> wrong, a logical conclusion is that the error is elsewhere. For
> example, almost any kind of memory corruption could result in this
> call subsequently failing in an erratic or unexplainable manner.
>
> There are important things missing from your post. How are prxParams
> (especially the jobj it holds) and the JNIEnv initialized? Since the
> native method is presumably called from a separate thread started from
> native code, you need to call AttachCurrentThread() somewhere or the
> JNIEnv won't be valid here.
>
> You should be cleaning up every object you create in this method.
> either with DeleteLocalRef(), or by wrapping the method in calls to
> Push/PopLocalFrame().
>
> Try to post a compilable example.
>
> /gordon
>
> --
Thx gordon. Your totally right with your advise. I added now all
neccessary code parts.. I did some testing this morining and what i
found out is pretty interesting.
C:
struct RxParams
{
XLhandle eventHandle;
long portHandle;
const char *callBackName;
jobject caller;
JNIEnv *env;
}typedef RXPARAMS;
JNIEXPORT jlong JNICALL Java_VectorXLDriverLib_setNotifier(JNIEnv
*env, jclass jcls, jobject portHandle, jint queueLevel , jobject
caller, jstring callBackName)
{
[...]
RXPARAMS prxParams;
prxParams.eventHandle = eventHandle;
prxParams.portHandle = ph;
prxParams.caller = caller;
prxParams.env = env;
prxParams.callBackName = (*env)->GetStringUTFChars(env,callBackName,
0);
listenCan(prxParams);
}
return xlStatus;
}
void listenCan(RXPARAMS par)
{
writeLog("In RxThread\n");
unsigned int msgsrx = RECEIVE_EVENT_SIZE;
jsize count;
jmethodID jmid;
jclass icls;
jboolean continueListening = 1;
char string[50];
JAVAOBJECT eventObj; //object used for callBack to java
RXPARAMS prxParams = par;
JNIEnv *env = par.env;
writeLog("Before get Structure XLCANEvent\n");
// Klasse des aufrufenden Java Objektes ermitteln:
icls = (*env)->GetObjectClass(env, prxParams.caller);
writeLog("before getMID: icls: %02x\n", icls);
jmid = (*env)->GetMethodID(env, icls,
prxParams.callBackName,"(LXLCanEvent;Ljava/lang/String

Z");
writeLog("after getMID\n");
if (jmid == 0){
writeLog("jmid == NULL\n");
}
eventObj = CreatejObject(env, "XLCanEvent");
writeLog("Before Get Field Ids\n");
jfieldID jFldTransId = (*env)->GetFieldID(env, eventObj.jcls,
"transid", "I");
jfieldID jfldPortHandle = (*env)->GetFieldID(env,
eventObj.jcls, "portHandle", "I");
jfieldID jfldFlag = (*env)->GetFieldID(env, eventObj.jcls,
"flags", "I");
jfieldID jfldCanId = (*env)->GetFieldID(env, eventObj.jcls,
"id", "J");
jint test = 5;
writeLog("CallBooleanMethod with Data\n");
// Methode "intern" des aufrufenden Java Objektes aufrufen:
(*env)->SetIntField(env, eventObj.ref, jFldTransId, test);
(*env)->SetIntField(env, eventObj.ref, jfldPortHandle, test );
(*env)->SetIntField(env, eventObj.ref, jfldFlag, test );
(*env)->SetLongField(env, eventObj.ref, jfldCanId, test );
const char *pWelt = "Hallo Welt";
jstring jStr = NULL;
jStr = (*env)->NewStringUTF(env, pWelt);
if (jStr != NULL){
jsize size = (*env)->GetStringUTFLength(env,jStr);
writeLog("Is Not Null. Size: %d \n", size);
}
else
writeLog("Is Null\n");
continueListening = (*env)->CallBooleanMethod(env, prxParams.caller,
jmid, eventObj, jStr);
#ifdef DEBUG
writeLog("Listener has been terminated");
#endif
}
JAVAOBJECT CreatejObject(JNIEnv *env , char * className)
{
jclass jcls;
jfieldID jfid;
jmethodID jmid;
jobject jobj;
JAVAOBJECT javaObj;
javaObj.ref = NULL;
javaObj.jcls = 0;
javaObj.jcls = (*env)->FindClass(env, className);
if (javaObj.jcls == NULL)
{
writeLog("Error FindClass\n");
return javaObj;
}
//Get constructor id
jmid = (*env)->GetMethodID(env, javaObj.jcls, "<init>","()V");
if (jmid == NULL)
{
writeLog("Error GetMethodID\n");
return javaObj;
}
//create new object
javaObj.ref = (*env)->NewObject(env, javaObj.jcls, jmid);
if (jobj == NULL)
{
writeLog("Error NewObject\n");
return javaObj;
}
return javaObj;
}
Java Code:
public class VectorCanLib implements Runnable{
//Returns the Id of the gen
public synchronized long registerListener(VectorXlLibraryNotifier
callBack)
{
closeNotify = false;
if(notifyThread == null){
notifyThread = new Thread(this);
notifyThread.start();
}
listeners.add(callBack);
return 0;
}
public void run() {
VectorXLDriverLib.setNotifier(portHandle, queueLevel, this,
"internalNotifyCallback");
System.out.println("Internal notifier closed");
}
private synchronized boolean internalNotifyCallback(XLCanEvent e,
String obj)
{
//TODO: Alle abgespeicherten callbacks nacheinander benachrichtigen
if(e != null){
System.out.println("Received: TransID: " + e.transid + " PH "+
e.portHandle +" CANID "+ e.id);
}
else{
;//System.out.println("null call received");
}
if(obj != null)
{
System.out.println(obj.length());
System.out.println("object is not null : " + obj.toString());
}
if(closeNotify){
System.out.println("CloseNotify is " + closeNotify);
}
return !closeNotify;
}
}
public abstract class VectorXLDriverLib{
[.....]
public static native long setNotifier(XLPortHandle portHandle, int
queueLevel, Object caller, String callBackName);
static {
try{
System.load(System.getProperty("user.dir") + "\\" + "MyDll.dll");
}
catch(Exception e) {
e.printStackTrace();
}
}
public class XLCanEvent {
public char channelIndex;
public int transid; //internal use only
public int portHandle; //internal use only
public long id;/
public int flags;
}
Now the example should contain everything neccessary. What i found out
is that if i replace in the function listenCan()
continueListening = (*env)->CallBooleanMethod(env, prxParams.caller,
jmid, eventObj, jStr);
with
continueListening = (*env)->CallBooleanMethod(env, prxParams.caller,
jmid, NULL, jStr);
than the string obj will be correctyl given to java! Could it be that
the eventObj overrides the string reference??? I changed nothing else
in the code expect of these line!
Thanks for your help in advance