The C File

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.