A. Apvrille
August 17th, 1999, 09:46 AM
Hello,
I'm trying to link some C function with this prototype :
HANDLE myFunc([IN] HWND, [IN] unsigned char *, [OUT] WORD *, [OUT] WORD *, [OUT] unsigned char *)
Don't bother too much about HANDLE, HWND, WORD etc they're just pointer values, longs etc. My actual problem is that my function returns many values (a HANDLE, two
WORDs and an unsigned char -- actually it's a string).
To manage to map pointers on Words, I built up a class Word, with a single parameter value (an int).
In C code (JNI), I therefore need to modify the Word object and set its value. I've read this is possible with SetIntField method and so on.
... but in my case, I can't get it to work (and I can't see my error) : object doesn't seem to be modified... Maybe I haven't got the right fieldID, or the right class, I don't understand...
Here's my code, it isn't long. If someone can help me out...
PS. I've been through the JNI section, in Codeguru, and found an interesting Java Tip of Geoff Friesen, but I seem to be doing it correctly, so I don't understand.
in Word.java
class Word {
public int value;
Word(){}
Word(int i){ value = i; }
}
in GDAPI.java
class GDAPI {
static {
// link to my DLL
System.loadLibrary("gdirect");
}
public native long open(long hWnd,
String szTitle,
Word pIsOk,
Word pIsInit,
String szName //out
);
public static void main(String args[]){
String name = "toto";
Word ok = new Word(0);
Word init = new Word(0);
GDAPI api= new GDAPI();
System.out.println("In JAVA, before call to open");
long h = api.open(0,"Coucou",ok,init,name);
System.out.println("In Java after call :");
System.out.println("\tok="+ok.value);
System.out.println("\tinit="+init.value);
System.out.println("\tname="+name);
System.out.println("\th="+h);
[...]
}
}
In C :
JNIEXPORT jlong JNICALL
Java_GDAPI_open(JNIEnv *env,
jobject obj_this,
jlong hwnd, // in
jstring jstrTitle, // in (not out !)
jobject joIsOk, // only out
jobject joIsInit, // only out
jstring jstrName){ // only out
char *sztitle;
char szname[128];
WORD w_ok,w_init;
HANDLE h;
jclass cls_ok, cls_init;
jfieldID fid_ok,fid_init;
printf("> Java_GDAPI_open\n");
// initialisations
obj_this = obj_this;
h = NULL;
w_ok = 0;
w_init = 0;
sztitle = (char *)(*env)->GetStringUTFChars(env,jstrTitle,0);
// call to real C Function
printf("CFunction(hwnd=%08lx,title=%s,&w_ok=%08lx, &w_init=%08lx,szname=%s)\n",hwnd,sztitle,&w_ok,&w_init,szname);
h = CFunction((HWND) hwnd, (unsigned char*)sztitle, &w_ok, &w_init, (unsigned char*)szname);
printf("returns h=%08lx w_ok=%d w_init=%d szname=%s\n",h,w_ok,w_init,szname);
// updating IsOk object
printf("updating isOk\n");
cls_ok = (*env)->GetObjectClass(env,joIsOk);
fid_ok = (*env)->GetFieldID(env,cls_ok,"value","I");
if (fid_ok == 0) return 0;
(*env)->SetIntField(env,cls_ok,fid_ok, (jint) w_ok);
// updating IsInit
printf("updating IsInit\n");
cls_init = (*env)->GetObjectClass(env,joIsInit);
fid_init = (*env)->GetFieldID(env,cls_init,"value","I");
if (fid_init == 0) return 0;
(*env)->SetIntField(env,cls_init,fid_init, (jint) w_init);
// updating string object
printf("updating string \n");
jstrName = (*env)->NewStringUTF(env,szname);
// free
printf("freeing \n");
(*env)->ReleaseStringUTFChars(env, jstrTitle, sztitle);
printf("< Java_GDAPI_open\n");
return (jlong) h;
}
--
Axelle Apvrille - MSI
I'm trying to link some C function with this prototype :
HANDLE myFunc([IN] HWND, [IN] unsigned char *, [OUT] WORD *, [OUT] WORD *, [OUT] unsigned char *)
Don't bother too much about HANDLE, HWND, WORD etc they're just pointer values, longs etc. My actual problem is that my function returns many values (a HANDLE, two
WORDs and an unsigned char -- actually it's a string).
To manage to map pointers on Words, I built up a class Word, with a single parameter value (an int).
In C code (JNI), I therefore need to modify the Word object and set its value. I've read this is possible with SetIntField method and so on.
... but in my case, I can't get it to work (and I can't see my error) : object doesn't seem to be modified... Maybe I haven't got the right fieldID, or the right class, I don't understand...
Here's my code, it isn't long. If someone can help me out...
PS. I've been through the JNI section, in Codeguru, and found an interesting Java Tip of Geoff Friesen, but I seem to be doing it correctly, so I don't understand.
in Word.java
class Word {
public int value;
Word(){}
Word(int i){ value = i; }
}
in GDAPI.java
class GDAPI {
static {
// link to my DLL
System.loadLibrary("gdirect");
}
public native long open(long hWnd,
String szTitle,
Word pIsOk,
Word pIsInit,
String szName //out
);
public static void main(String args[]){
String name = "toto";
Word ok = new Word(0);
Word init = new Word(0);
GDAPI api= new GDAPI();
System.out.println("In JAVA, before call to open");
long h = api.open(0,"Coucou",ok,init,name);
System.out.println("In Java after call :");
System.out.println("\tok="+ok.value);
System.out.println("\tinit="+init.value);
System.out.println("\tname="+name);
System.out.println("\th="+h);
[...]
}
}
In C :
JNIEXPORT jlong JNICALL
Java_GDAPI_open(JNIEnv *env,
jobject obj_this,
jlong hwnd, // in
jstring jstrTitle, // in (not out !)
jobject joIsOk, // only out
jobject joIsInit, // only out
jstring jstrName){ // only out
char *sztitle;
char szname[128];
WORD w_ok,w_init;
HANDLE h;
jclass cls_ok, cls_init;
jfieldID fid_ok,fid_init;
printf("> Java_GDAPI_open\n");
// initialisations
obj_this = obj_this;
h = NULL;
w_ok = 0;
w_init = 0;
sztitle = (char *)(*env)->GetStringUTFChars(env,jstrTitle,0);
// call to real C Function
printf("CFunction(hwnd=%08lx,title=%s,&w_ok=%08lx, &w_init=%08lx,szname=%s)\n",hwnd,sztitle,&w_ok,&w_init,szname);
h = CFunction((HWND) hwnd, (unsigned char*)sztitle, &w_ok, &w_init, (unsigned char*)szname);
printf("returns h=%08lx w_ok=%d w_init=%d szname=%s\n",h,w_ok,w_init,szname);
// updating IsOk object
printf("updating isOk\n");
cls_ok = (*env)->GetObjectClass(env,joIsOk);
fid_ok = (*env)->GetFieldID(env,cls_ok,"value","I");
if (fid_ok == 0) return 0;
(*env)->SetIntField(env,cls_ok,fid_ok, (jint) w_ok);
// updating IsInit
printf("updating IsInit\n");
cls_init = (*env)->GetObjectClass(env,joIsInit);
fid_init = (*env)->GetFieldID(env,cls_init,"value","I");
if (fid_init == 0) return 0;
(*env)->SetIntField(env,cls_init,fid_init, (jint) w_init);
// updating string object
printf("updating string \n");
jstrName = (*env)->NewStringUTF(env,szname);
// free
printf("freeing \n");
(*env)->ReleaseStringUTFChars(env, jstrTitle, sztitle);
printf("< Java_GDAPI_open\n");
return (jlong) h;
}
--
Axelle Apvrille - MSI