The basic form of any JNI function in our case will be something like Example 2-4.
Example 2-4. gtk_GtkButton.c
JNIEXPORT jlong JNICALL <functionname> (JNIEnv * env, jobject obj, ...) { Define some variables Convert from JNI types to C/GLib types Call the GDK/GTK/GNOME function Convert C/GLib types to JNI types (if necessary) Clean up behind us (if necessary) Return JNI data (if ncessary) } |
This means that we will generate the code in Example 2-5 for GtkButton.
Example 2-5. gtk_GtkButton.c
#include "gtk_GtkButton.h" #ifdef __cplusplus extern "C" { #endif JNIEXPORT jlong JNICALL Java_gtk_GtkButton_nativenew (JNIEnv * env, jobject obj) { GtkButton * _result; jlong _jresult; _result = (GtkButton *)gtk_button_new(); *(GtkButton **)&_jresult = _result; return _jresult; } JNIEXPORT jlong JNICALL Java_gtk_GtkButton_nativenewWithLabel (JNIEnv * env, jobject obj, jstring j_label) { char * _arg0; GtkButton * _result; jlong _jresult; _arg0 = (j_label) ? (char *)(*env)->GetStringUTFChars(env, j_label, 0): NULL; _result = (GtkButton *)gtk_button_new_with_label(_arg0); if(_arg0) (*env)->ReleaseStringUTFChars(env, j_label, _arg0); *(GtkButton **)&_jresult = _result; return _jresult; } JNIEXPORT void JNICALL Java_gtk_GtkButton_pressed (JNIEnv * env, jobject obj) { GtkButton * cptr; jfieldID fid; jclass cls; jlong jptr; cls = (*env)->GetObjectClass(env, obj); fid = (*env)->GetFieldID(env, cls, "nativepeer", "J"); jptr = (*env)->GetLongField(env, obj, fid); cptr = *(GtkButton **)&jptr; gtk_button_pressed(cptr); } JNIEXPORT void JNICALL Java_gtk_GtkButton_released (JNIEnv * env, jobject obj) { GtkButton * cptr; jfieldID fid; jclass cls; jlong jptr; cls = (*env)->GetObjectClass(env, obj); fid = (*env)->GetFieldID(env, cls, "nativepeer", "J"); jptr = (*env)->GetLongField(env, obj, fid); cptr = *(GtkButton **)&jptr; gtk_button_released(cptr); } JNIEXPORT void JNICALL Java_gtk_GtkButton_clicked (JNIEnv * env, jobject obj) { GtkButton * cptr; jfieldID fid; jclass cls; jlong jptr; cls = (*env)->GetObjectClass(env, obj); fid = (*env)->GetFieldID(env, cls, "nativepeer", "J"); jptr = (*env)->GetLongField(env, obj, fid); cptr = *(GtkButton **)&jptr; gtk_button_clicked(cptr); } JNIEXPORT void JNICALL Java_gtk_GtkButton_enter (JNIEnv * env, jobject obj) { GtkButton * cptr; jfieldID fid; jclass cls; jlong jptr; cls = (*env)->GetObjectClass(env, obj); fid = (*env)->GetFieldID(env, cls, "nativepeer", "J"); jptr = (*env)->GetLongField(env, obj, fid); cptr = *(GtkButton **)&jptr; gtk_button_enter(cptr); } JNIEXPORT void JNICALL Java_gtk_GtkButton_leave (JNIEnv * env, jobject obj) { GtkButton * cptr; jfieldID fid; jclass cls; jlong jptr; cls = (*env)->GetObjectClass(env, obj); fid = (*env)->GetFieldID(env, cls, "nativepeer", "J"); jptr = (*env)->GetLongField(env, obj, fid); cptr = *(GtkButton **)&jptr; gtk_button_leave(cptr); } #ifdef __cplusplus } #endif |
We will not discuss the code in detail but will leave it to you to make sure that you understand the code taht we wants to generate. As mentioned before one can find various Tutorials and Documentation at Javasoft.
As one can see from the example a lot of the code repeats. This is one of the biggest reasons that the Java-GNOME team decided on a parsing approach than hand coded wrapper classes.