1. 背景: 实现了一个Linux C核心模块,同时实现了Console 与 GTK 的显示,现在需要实现一个Java的界面程序。
2. 功能: GUI 向后台注册一个回调函数,核心模块得到一些结果后,调用注册的回调函数向 GUI 返回数据。
测试 JNI 代码如下,具体JNI编程可以参考资料(像 JNI 编程指南):
C语言代码:
-
[File: call_back.h]
-
-
#ifndef _CALL_BACK_H_
-
#define _CALL_BACK_H_
-
-
#include <time.h>
-
-
#ifdef __cplusplus
-
extern \"C\" {
-
#endif
-
-
struct _CallBackBody;
-
typedef struct _CallBackBody CallBackBody;
-
-
typedef void (*CallBackInfoPrintFunc)(
-
unsigned long total_line,
-
int code_line,
-
time_t modify_time,
-
const char * file_name
-
);
-
-
CallBackBody* callback_create(CallBackInfoPrintFunc info_print);
-
-
int callback_run(CallBackBody* thiz);
-
-
void callback_destroy(CallBackBody* thiz);
-
-
#ifdef __cplusplus
-
}
-
#endif
-
-
#endif/*_CALL_BACK_H_*/
-
[File: call_back.c]
-
-
#include \"call_back.h\"
-
#include <stdlib.h>
-
-
struct _CallBackBody
-
{
-
int call_num;
-
CallBackInfoPrintFunc print;
-
};
-
-
CallBackBody* callback_create(CallBackInfoPrintFunc info_print)
-
{
-
CallBackBody* thiz = (CallBackBody *)malloc(sizeof(CallBackBody));
-
-
if (thiz != NULL)
-
{
-
thiz->print = info_print;
-
thiz->call_num = 0;
-
}
-
-
return thiz;
-
}
-
-
int callback_run(CallBackBody* thiz)
-
{
-
if (thiz != NULL && thiz->print != NULL)
-
{
-
++thiz->call_num;
-
unsigned long total_line = thiz->call_num * 100 + 10;
-
int code_line = thiz->call_num * 100 - 20;
-
code_line = code_line < 0 ? 0 : code_line;
-
time_t now;
-
time(&now);
-
char* file_name = \"/home/vincent/call_back.c\";
-
-
thiz->print(total_line, code_line, now, file_name);
-
-
return 1;
-
}
-
-
return -1;
-
}
-
-
void callback_destroy(CallBackBody* thiz)
-
{
-
free(thiz);
-
-
return;
-
}
Java代码:
[File: JniInterface.java]
public class JniInterface
{
private static native void callbackInitIds();
public static native boolean callbackCreate();
public static native boolean callbackRun(String file);
public static native void callbackDestroy();
public static void DataShowCallBackFunc(
long totalLine,
int codeLine,
String modifyTime,
String fileName
)
{
System.out.println("[Info]: totalLine = " + totalLine
+ " codeLine = " + codeLine
+ " modifyTime = " + modifyTime
+ " fileName = " + fileName);
}
public static void main(String[] args)
{
if (JniInterface.callbackCreate())
{
try
{
while (true)
{
if (JniInterface.callbackRun("/pet/vincent_deng/test"))
{
}
else
{
System.out.println("[Info]: Run false...");
}
Thread.sleep(5000);
}
}
catch (Exception ex)
{
}
finally
{
JniInterface.callbackDestroy();
}
}
else
{
System.out.println("[Info]: Create false...");
}
}
static
{
System.loadLibrary("callback");
callbackInitIds();
}
}
编译 JniInterface.java 得到 JniInterface.class, 再使用 javah 命令【javah JniInterface】得到 JniInterface.h 文件,拷贝 JniInterface.h 为 JniInterface.c 并修改:
-
[File: JniInterface.h]
-
-
/* DO NOT EDIT THIS FILE - it is machine generated */
-
#include <jni.h>
-
/* Header for class JniInterface */
-
-
#ifndef _Included_JniInterface
-
#define _Included_JniInterface
-
#ifdef __cplusplus
-
extern \"C\" {
-
#endif
-
/*
-
* Class: JniInterface
-
* Method: callbackInitIds
-
* Signature: ()V
-
*/
-
JNIEXPORT void JNICALL Java_JniInterface_callbackInitIds
-
(JNIEnv *, jclass);
-
-
/*
-
* Class: JniInterface
-
* Method: callbackCreate
-
* Signature: ()Z
-
*/
-
JNIEXPORT jboolean JNICALL Java_JniInterface_callbackCreate
-
(JNIEnv *, jclass);
-
-
/*
-
* Class: JniInterface
-
* Method: callbackRun
-
* Signature: (Ljava/lang/String;)Z
-
*/
-
JNIEXPORT jboolean JNICALL Java_JniInterface_callbackRun
-
(JNIEnv *, jclass, jstring);
-
-
/*
-
* Class: JniInterface
-
* Method: callbackDestroy
-
* Signature: ()V
-
*/
-
JNIEXPORT void JNICALL Java_JniInterface_callbackDestroy
-
(JNIEnv *, jclass);
-
-
#ifdef __cplusplus
-
}
-
#endif
-
#endif
-
[File: JniInterface.c]
-
-
/* Source for class JniInterface */
-
#include \"JniInterface.h\"
-
#include \"call_back.h\"
-
#include \"time.h\"
-
-
#define CALLBACK_FUNC_NAME \"DataShowCallBackFunc\"
-
-
static CallBackBody* s_callBackBody = NULL;
-
static jclass s_class = NULL;
-
static jmethodID s_methodId = NULL;
-
static JNIEnv* s_env = NULL;
-
-
void callBackFunc(
-
unsigned long total_line,
-
int code_line,
-
time_t modify_time,
-
const char * file_name
-
)
-
{
-
char buf[512];
-
struct tm tm_buf;
-
-
if (strftime(buf, sizeof(buf), \"[%G-%m-%d %H:%M:%S]\", localtime_r(&modify_time, &tm_buf)) == 0)
-
{
-
buf[0] = \'\\0\';
-
}
-
-
jlong totalLine = total_line;
-
jint codeLine = code_line;
-
jstring modifyTime = (*s_env)->NewStringUTF(s_env, buf);
-
jstring fileName = (*s_env)->NewStringUTF(s_env, file_name);
-
(*s_env)->CallStaticVoidMethod(
-
s_env,
-
s_class,
-
s_methodId,
-
totalLine,
-
codeLine,
-
modifyTime,
-
fileName);
-
}
-
-
/*
-
* Class: JniInterface
-
* Method: callbackInitIds
-
* Signature: ()V
-
*/
-
JNIEXPORT void JNICALL Java_JniInterface_callbackInitIds
-
(JNIEnv *env, jclass cls)
-
{
-
s_methodId = (*env)->GetStaticMethodID(env, cls, CALLBACK_FUNC_NAME, \"(JILjava/lang/String;Ljava/lang/String;)V\");
-
//s_env = (*env)->NewGlobalRef(env, env);
-
s_env = env;
-
s_class = (*env)->NewGlobalRef(env, cls);
-
}
-
-
/*
-
* Class: JniInterface
-
* Method: callbackCreate
-
* Signature: ()Z
-
*/
-
JNIEXPORT jboolean JNICALL Java_JniInterface_callbackCreate
-
(JNIEnv *env, jclass cls)
-
{
-
if (s_methodId == NULL
-
|| s_env == NULL
-
|| s_class == NULL)
-
{
-
return JNI_FALSE;
-
}
-
-
if (s_callBackBody == NULL)
-
{
-
s_callBackBody = callback_create(callBackFunc);
-
}
-
-
return s_callBackBody == NULL ? JNI_FALSE : JNI_TRUE;
-
}
-
-
/*
-
* Class: JniInterface
-
* Method: callbackRun
-
* Signature: (Ljava/lang/String;)Z
-
*/
-
JNIEXPORT jboolean JNICALL Java_JniInterface_callbackRun
-
(JNIEnv *env, jclass cls, jstring file)
-
{
-
int rst;
-
const jbyte *str = (*env)->GetStringUTFChars(env, file, NULL);
-
-
if (str == NULL)
-
{
-
return JNI_FALSE;
-
}
-
-
rst = callback_run(s_callBackBody);
-
-
(*env)->ReleaseStringUTFChars(env, file, str);
-
-
return rst < 0 ? JNI_FALSE : JNI_TRUE;
-
}
-
-
/*
-
* Class: JniInterface
-
* Method: callbackDestroy
-
* Signature: ()V
-
*/
-
JNIEXPORT void JNICALL Java_JniInterface_callbackDestroy
-
(JNIEnv *env, jclass cls)
-
{
-
s_env = NULL;
-
//(*env)->DeleteGlobalRef(env, s_env);
-
(*env)->DeleteGlobalRef(env, s_class);
-
callback_destroy(s_callBackBody);
-
s_callBackBody = NULL;
-
}
最后将 call_back.c 和 JniInterface.c 编译为 libcallback.so, 再执行 Java文件即可,简单Makefile, 其中的路径【/usr/java/default/include/】 和 【/usr/java/default/include/linux】需要修改为系统对应的jdk路径:
-
.PHONY: clean
-
-
libcallback.so: call_back.o JniInterface.o
-
gcc -Wall -fPIC -rdynamic -shared -o $@ $^
-
-
%.o: %.c
-
gcc -Wall -c -o $@ -I./ -I/usr/java/default/include/ -I/usr/java/default/include/linux $(filter %.c, $^)
-
-
clean:
-
-rm *.so *.o
执行结果如下:
-
[tester@dellquad JavaCallC]$ export LD_LIBRARY_PATH=.
-
[tester@dellquad JavaCallC]$ make
-
gcc -Wall -c -o call_back.o -I./ -I/usr/java/default/include/ -I/usr/java/default/include/linux call_back.c
-
gcc -Wall -c -o JniInterface.o -I./ -I/usr/java/default/include/ -I/usr/java/default/include/linux JniInterface.c
-
gcc -Wall -fPIC -rdynamic -shared -o libcallback.so call_back.o JniInterface.o
-
[tester@dellquad JavaCallC]$ javac JniInterface.java
-
[tester@dellquad JavaCallC]$ java JniInterface
-
[Info]: totalLine = 110 codeLine = 80 modifyTime = [2013-05-10 12:15:43] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 210 codeLine = 180 modifyTime = [2013-05-10 12:15:48] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 310 codeLine = 280 modifyTime = [2013-05-10 12:15:53] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 410 codeLine = 380 modifyTime = [2013-05-10 12:15:58] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 510 codeLine = 480 modifyTime = [2013-05-10 12:16:03] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 610 codeLine = 580 modifyTime = [2013-05-10 12:16:08] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 710 codeLine = 680 modifyTime = [2013-05-10 12:16:13] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 810 codeLine = 780 modifyTime = [2013-05-10 12:16:18] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 910 codeLine = 880 modifyTime = [2013-05-10 12:16:23] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1010 codeLine = 980 modifyTime = [2013-05-10 12:16:28] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1110 codeLine = 1080 modifyTime = [2013-05-10 12:16:33] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1210 codeLine = 1180 modifyTime = [2013-05-10 12:16:38] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1310 codeLine = 1280 modifyTime = [2013-05-10 12:16:43] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1410 codeLine = 1380 modifyTime = [2013-05-10 12:16:48] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1510 codeLine = 1480 modifyTime = [2013-05-10 12:16:53] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1610 codeLine = 1580 modifyTime = [2013-05-10 12:16:58] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1710 codeLine = 1680 modifyTime = [2013-05-10 12:17:03] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1810 codeLine = 1780 modifyTime = [2013-05-10 12:17:08] fileName = /home/vincent/call_back.c
-
[Info]: totalLine = 1910 codeLine = 1880 modifyTime = [2013-05-10 12:17:13] fileName = /home/vincent/call_back.c
-
-
[tester@dellquad JavaCallC]$
代码:上传JavaCallC.tar.bz2 说不支持该类型文件,改成了 JavaCallC.tar.bz2.txt 上传,下载后改回来即可。
JavaCallC.tar.bz2.txt
阅读(1958) | 评论(0) | 转发(0) |