1. create Message.java, define native function and load library
[dennis@localhost jni]$ cat Message.java
class Message
{
public native int writeMessage(int type, char page_num, String content);
public native int getCPUTemperature();
public native int getHDDTemperature();
static
{
System.loadLibrary("Message");
}
}
2. run ‘javac Message.java’ to generate Message.class
[dennis@localhost jni]$ javac Message.java
3. run ‘javah Message’ to generate Message.h
[dennis@localhost jni]$ javah Message
[dennis@localhost jni]$ cat Message.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Message */
#ifndef _Included_Message
#define _Included_Message
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Message
* Method: writeMessage
* Signature: (ICLjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_Message_writeMessage
(JNIEnv *, jobject, jint, jchar, jstring);
/*
* Class: Message
* Method: getCPUTemperature
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Message_getCPUTemperature
(JNIEnv *, jobject);
/*
* Class: Message
* Method: getHDDTemperature
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Message_getHDDTemperature
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
4. create Message.c, and implement function
[dennis@localhost jni]$ cat Message.c
#include <jni.h>
#include <stdio.h>
#include "Message.h"
int iCpu;
int iHdd;
int iMainboard;
int iFan;
void ReadTemperatureIni()
{
iCpu = 37;
iHdd = 28;
iMainboard = 30;
iFan = 3200;
printf("call %s %s %d\n", __FILE__, __func__, __LINE__);
}
void send_msg(const short code, const char page, const char *content)
{
printf("code=%d, page=%d, content=%s\n", code, page, content);
printf("call %s %s %d\n", __FILE__, __func__, __LINE__);
}
JNIEXPORT jint JNICALL Java_Message_getCPUTemperature(JNIEnv *env, jobject obj)
{
ReadTemperatureIni();
return iCpu;
}
JNIEXPORT jint JNICALL Java_Message_getHDDTemperature(JNIEnv *env, jobject obj)
{
ReadTemperatureIni();
return iHdd;
}
JNIEXPORT jint JNICALL Java_Message_getMainboardTemperature (JNIEnv *env, jobject obj)
{
ReadTemperatureIni();
return iMainboard;
}
JNIEXPORT jint JNICALL Java_Message_getCPUFanSpeed (JNIEnv *env, jobject obj)
{
ReadTemperatureIni();
return iFan;
}
JNIEXPORT jint JNICALL Java_Message_writeMessage
(JNIEnv *env, jobject obj, jint type, jchar page_num, jstring content)
{
/* c code use: (*env)-> */
/* c++ code use: env-> */
const jbyte *str = (const jbyte *)(*env)->GetStringUTFChars(env,content,JNI_FALSE);
send_msg(type, page_num, (const char*)str);
(*env)->ReleaseStringUTFChars(env,content,(const char *)str);
return 0;
}
5. start to compile file to dynamic library, then copy the *.so file to /usr/lib64/
[dennis@localhost jni]$ cat Makefile
CC = gcc
CFLAGS = -Wall -shared -fPIC
# change the directory for YOUR OS
JAVA_INC = -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.5.0.1.fc20.x86_64/include/ \
-I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.5.0.1.fc20.x86_64/include/linux
TARGET = libMessage.so
all:$(TARGET)
libMessage.so: Message.c
$(CC) $(CFLAGS) $(JAVA_INC) -o $@ $^
.PHONY:clean
clean:
rm -f *.class $(TARGET)
[dennis@localhost jni]$ make
gcc -Wall -shared -fPIC -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.5.0.1.fc20.x86_64/include/ -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.5.0.1.fc20.x86_64/include/linux -o libMessage.so Message.c
[dennis@localhost jni]$ su -c 'cp libMessage.so /usr/lib64'
6. create Test.java, a sample code to test interface function
[dennis@localhost jni]$ cat Test.java
public class Test
{
public static void main(String argv[])
{
new Test();
}
public Test()
{
char type = 0x1F;
char page = 1;
String content = "Test Message";
int ret = new Message().writeMessage(type, page, content);
int cpu=new Message().getCPUTemperature();
System.out.println(cpu);
int hdd=new Message().getHDDTemperature();
System.out.println(hdd);
}
}
7. run ‘javac Test.java’
[dennis@localhost jni]$ javac Test.java
8. run ‘java Test’
[dennis@localhost jni]$ java Test
code=31, page=1, content=Test Message
call Message.c send_msg 22
call Message.c ReadTemperatureIni 16
37
call Message.c ReadTemperatureIni 16
28
A full version Makefile, support compile java code
#################################################################
# Makefile
# For JNI project on Fedora x86_64 release 20
# Create by Dennis
# 2014-07-18
#
# HOW TO MAKE A JNI PROJECT
# 1. create Message.java, define native function and load library
# 2. run 'javac Message.java' to generate Message.class
# 3. run 'javah Message' to generate Message.h
# 4. create Message.c, and implement function
# 5. start to compile file to dynamic library, then copy the *.so
# file to /usr/lib64/
# 6. create Test.java, a sample code to test interface function
# 7. run 'javac Test.java' to generate Test.class
# 7. run 'java Test'
#################################################################
CC = gcc
JAVAC = javac
CFLAGS = -Wall -shared -fPIC
# change the directory for YOUR OS
JAVA_INC = -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.5.0.1.fc20.x86_64/include/ \
-I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.5.0.1.fc20.x86_64/include/linux
TARGET = libMessage.so Test.class
all:$(TARGET)
libMessage.so: Message.c
$(CC) $(CFLAGS) $(JAVA_INC) -o $@ $^
Test.class:
$(JAVAC) Test.java
.PHONY:clean
clean:
rm -f *.class $(TARGET)
Reference