Friday, February 09, 2007

Using Native Data Structures in JNI

Linking a static library to Java using JNI

Beginning JNI Linux tutorial for Netbeans

Once I had accomplished the above with complete success, I extended the experiment by linking my static library (.a) to the dynamic library, and calling the static library function from the dynamic library function.

My HelloWorldNative.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class helloworld_Main */

#ifndef _Included_helloworld_Main
#define _Included_helloworld_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: helloworld_Main
* Method: nativePrint
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_helloworld_Main_nativePrint
(JNIEnv *, jobject);

/*
* Class: helloworld_Main
* Method: nativePrintNumber
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_helloworld_Main_nativePrintNumber
(JNIEnv *, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

My HelloWorldNative.c:
#include <jni.h>

#include <stdio.h>

#include "../HelloWorldNative.h"

void hello();
void hello_number(int i);

JNIEXPORT void JNICALL Java_helloworld_Main_nativePrint(JNIEnv *env, jobject obj)
{
hello();
}

JNIEXPORT void JNICALL Java_helloworld_Main_nativePrintNumber
(JNIEnv *env, jobject obj, jint ji)
{
hello_number(ji);
}

My Main.java:
/*
* Main.java
*
* Created on February 9, 2007, 3:48 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package helloworld;

/**
*
* @author thomas
*/
public class Main {

private native void nativePrint();
private native void nativePrintNumber(int i);
/** Creates a new instance of Main */
public Main() {
}

static {
System.load("/home/thomas/src/c/testlib/HelloWorldNative/dist/HelloWorldNative.so");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main me = new Main();
me.nativePrint();
me.nativePrintNumber(2);
me.nativePrintNumber(5);
// TODO code application logic here
}

}

Linking a static library to Java using JNI

Beginning JNI Linux tutorial for Netbeans

Once I had accomplished the above with complete success, I extended the experiment by linking my static library (.a) to the dynamic library, and calling the static library function from the dynamic library function.

My HelloWorldNative.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class helloworld_Main */

#ifndef _Included_helloworld_Main
#define _Included_helloworld_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: helloworld_Main
* Method: nativePrint
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_helloworld_Main_nativePrint
(JNIEnv *, jobject);

/*
* Class: helloworld_Main
* Method: nativePrintNumber
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_helloworld_Main_nativePrintNumber
(JNIEnv *, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

My HelloWorldNative.c:
#include

#include

#include "../HelloWorldNative.h"

void hello();
void hello_number(int i);

JNIEXPORT void JNICALL Java_helloworld_Main_nativePrint(JNIEnv *env, jobject obj)
{
hello();
}

JNIEXPORT void JNICALL Java_helloworld_Main_nativePrintNumber
(JNIEnv *env, jobject obj, jint ji)
{
hello_number(ji);
}

My Main.java:
/*
* Main.java
*
* Created on February 9, 2007, 3:48 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package helloworld;

/**
*
* @author thomas
*/
public class Main {

private native void nativePrint();
private native void nativePrintNumber(int i);
/** Creates a new instance of Main */
public Main() {
}

static {
System.load("/home/thomas/src/c/testlib/HelloWorldNative/dist/HelloWorldNative.so");
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main me = new Main();
me.nativePrint();
me.nativePrintNumber(2);
me.nativePrintNumber(5);
// TODO code application logic here
}

}

Thursday, February 08, 2007

Link java to a static library.

See last post, assume testlib has a void hello(void) function.

Step 1: Create a wrapper class.
public class TestLibWrapper {
public static native void hello();

static {
System.loadLibrary("testlib");
}
}

Step 2: Compile wrapper class.
javac TestLibWrapper.java

Step 3: Run javah to create C header and stub file.
javah TestLibWrapper

Step 4...

GNUmakefile for a basic library

GNUmakefile for a static library, testlib.a, including a single file, hello.c

OBJS = hello.o

CFILES := ${OBJS:.o=.c}
LDFLAGS =
ARFLAGS = rcv

all:: testlib.a

testlib.a: ${OBJS}
@$(AR) ${ARFLAGS} $@ $?

clean::
@$(RM) ${OBJS} testlib.a

Labels:

Sunday, February 04, 2007

More on update-alternatives

It appears that update-alternatives is a very handy facility in Debian derivatives for keeping track of the preferred application for specific tasks.

This seems to be a much SAFER than Windows way of handling things (i.e., let the application try to set itself as the default handler--a la IE vs. Firefox, whatever audio player you use, etc...).

This also seems to be much cleaner than what I've experienced in the past with Linux--maybe trying to override one browser with another, creating a random soft link, etc...

All such alternatives can be seen in the /etc/alternatives directory. On a Kubuntu 6.10 (Edgy Eft) box, one finds among the alternatives java, pager, x-terminal-emulator, x-window-manager, and x-www-browser. Some alternatives are used to point to specific versions of a program.

"update-alternatives --display " will display information about which alternative is selected.

"update-alternatives --list " will list alternatives.

"update-alternatives --config " allows the selection of a specific alternative.

The files which control the list of alternatives are in /var/lib/dpkg/alternatives.

Labels: