Chinaunix首页 | 论坛 | 博客
  • 博客访问: 75443
  • 博文数量: 22
  • 博客积分: 145
  • 博客等级: 入伍新兵
  • 技术积分: 181
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-07 16:43
文章分类

全部博文(22)

文章存档

2018年(5)

2017年(2)

2013年(6)

2012年(4)

2011年(5)

我的朋友

分类: Java

2013-05-10 11:30:57

1. 背景: 实现了一个Linux C核心模块,同时实现了Console 与 GTK 的显示,现在需要实现一个Java的界面程序。
2. 功能: GUI 向后台注册一个回调函数,核心模块得到一些结果后,调用注册的回调函数向 GUI 返回数据。

测试 JNI 代码如下,具体JNI编程可以参考资料(像 JNI 编程指南):

C语言代码:

点击(此处)折叠或打开

  1. [File: call_back.h]

  2. #ifndef _CALL_BACK_H_
  3. #define _CALL_BACK_H_

  4. #include <time.h>

  5. #ifdef __cplusplus
  6. extern \"C\" {
  7. #endif

  8. struct _CallBackBody;
  9. typedef struct _CallBackBody CallBackBody;

  10. typedef void (*CallBackInfoPrintFunc)(
  11.             unsigned long total_line,
  12.             int code_line,
  13.             time_t modify_time,
  14.             const char * file_name
  15.             );

  16. CallBackBody* callback_create(CallBackInfoPrintFunc info_print);

  17. int callback_run(CallBackBody* thiz);

  18. void callback_destroy(CallBackBody* thiz);

  19. #ifdef __cplusplus
  20. }
  21. #endif

  22. #endif/*_CALL_BACK_H_*/

点击(此处)折叠或打开

  1. [File: call_back.c]

  2. #include \"call_back.h\"
  3. #include <stdlib.h>

  4. struct _CallBackBody
  5. {
  6.     int call_num;
  7.     CallBackInfoPrintFunc print;
  8. };

  9. CallBackBody* callback_create(CallBackInfoPrintFunc info_print)
  10. {
  11.     CallBackBody* thiz = (CallBackBody *)malloc(sizeof(CallBackBody));

  12.     if (thiz != NULL)
  13.     {
  14.         thiz->print = info_print;
  15.         thiz->call_num = 0;
  16.     }

  17.     return thiz;
  18. }

  19. int callback_run(CallBackBody* thiz)
  20. {
  21.     if (thiz != NULL && thiz->print != NULL)
  22.     {
  23.         ++thiz->call_num;
  24.         unsigned long total_line = thiz->call_num * 100 + 10;
  25.         int code_line = thiz->call_num * 100 - 20;
  26.         code_line = code_line < 0 ? 0 : code_line;
  27.         time_t now;
  28.         time(&now);
  29.         char* file_name = \"/home/vincent/call_back.c\";

  30.         thiz->print(total_line, code_line, now, file_name);
  31.         
  32.         return 1;
  33.     }

  34.     return -1;
  35. }

  36. void callback_destroy(CallBackBody* thiz)
  37. {
  38.     free(thiz);

  39.     return;
  40. }

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 并修改:

点击(此处)折叠或打开

  1. [File: JniInterface.h]

  2. /* DO NOT EDIT THIS FILE - it is machine generated */
  3. #include <jni.h>
  4. /* Header for class JniInterface */

  5. #ifndef _Included_JniInterface
  6. #define _Included_JniInterface
  7. #ifdef __cplusplus
  8. extern \"C\" {
  9. #endif
  10. /*
  11.  * Class: JniInterface
  12.  * Method: callbackInitIds
  13.  * Signature: ()V
  14.  */
  15. JNIEXPORT void JNICALL Java_JniInterface_callbackInitIds
  16.   (JNIEnv *, jclass);

  17. /*
  18.  * Class: JniInterface
  19.  * Method: callbackCreate
  20.  * Signature: ()Z
  21.  */
  22. JNIEXPORT jboolean JNICALL Java_JniInterface_callbackCreate
  23.   (JNIEnv *, jclass);

  24. /*
  25.  * Class: JniInterface
  26.  * Method: callbackRun
  27.  * Signature: (Ljava/lang/String;)Z
  28.  */
  29. JNIEXPORT jboolean JNICALL Java_JniInterface_callbackRun
  30.   (JNIEnv *, jclass, jstring);

  31. /*
  32.  * Class: JniInterface
  33.  * Method: callbackDestroy
  34.  * Signature: ()V
  35.  */
  36. JNIEXPORT void JNICALL Java_JniInterface_callbackDestroy
  37.   (JNIEnv *, jclass);

  38. #ifdef __cplusplus
  39. }
  40. #endif
  41. #endif

 

点击(此处)折叠或打开

  1. [File: JniInterface.c]

  2. /* Source for class JniInterface */
  3. #include \"JniInterface.h\"
  4. #include \"call_back.h\"
  5. #include \"time.h\"

  6. #define CALLBACK_FUNC_NAME \"DataShowCallBackFunc\"

  7. static CallBackBody* s_callBackBody = NULL;
  8. static jclass s_class = NULL;
  9. static jmethodID s_methodId = NULL;
  10. static JNIEnv* s_env = NULL;

  11. void callBackFunc(
  12.             unsigned long total_line,
  13.             int code_line,
  14.             time_t modify_time,
  15.             const char * file_name
  16.             )
  17. {
  18.     char buf[512];
  19.     struct tm tm_buf;

  20.     if (strftime(buf, sizeof(buf), \"[%G-%m-%d %H:%M:%S]\", localtime_r(&modify_time, &tm_buf)) == 0)
  21.     {
  22.         buf[0] = \'\\0\';
  23.     }

  24.     jlong totalLine = total_line;
  25.     jint codeLine = code_line;
  26.     jstring modifyTime = (*s_env)->NewStringUTF(s_env, buf);
  27.     jstring fileName = (*s_env)->NewStringUTF(s_env, file_name);
  28.     (*s_env)->CallStaticVoidMethod(
  29.                           s_env,
  30.                           s_class,
  31.                           s_methodId,
  32.                           totalLine,
  33.                           codeLine,
  34.                           modifyTime,
  35.                           fileName);
  36. }

  37. /*
  38.  * Class: JniInterface
  39.  * Method: callbackInitIds
  40.  * Signature: ()V
  41.  */
  42. JNIEXPORT void JNICALL Java_JniInterface_callbackInitIds
  43.   (JNIEnv *env, jclass cls)
  44. {
  45.     s_methodId = (*env)->GetStaticMethodID(env, cls, CALLBACK_FUNC_NAME, \"(JILjava/lang/String;Ljava/lang/String;)V\");
  46.     //s_env = (*env)->NewGlobalRef(env, env);
  47.     s_env = env;
  48.     s_class = (*env)->NewGlobalRef(env, cls);
  49. }

  50. /*
  51.  * Class: JniInterface
  52.  * Method: callbackCreate
  53.  * Signature: ()Z
  54.  */
  55. JNIEXPORT jboolean JNICALL Java_JniInterface_callbackCreate
  56.   (JNIEnv *env, jclass cls)
  57. {
  58.     if (s_methodId == NULL
  59.         || s_env == NULL
  60.         || s_class == NULL)
  61.     {
  62.         return JNI_FALSE;
  63.     }

  64.     if (s_callBackBody == NULL)
  65.     {
  66.         s_callBackBody = callback_create(callBackFunc);
  67.     }

  68.     return s_callBackBody == NULL ? JNI_FALSE : JNI_TRUE;
  69. }

  70. /*
  71.  * Class: JniInterface
  72.  * Method: callbackRun
  73.  * Signature: (Ljava/lang/String;)Z
  74.  */
  75. JNIEXPORT jboolean JNICALL Java_JniInterface_callbackRun
  76.   (JNIEnv *env, jclass cls, jstring file)
  77. {
  78.     int rst;
  79.     const jbyte *str = (*env)->GetStringUTFChars(env, file, NULL);
  80.     
  81.     if (str == NULL)
  82.     {
  83.         return JNI_FALSE;
  84.     }
  85.     
  86.     rst = callback_run(s_callBackBody);
  87.     
  88.     (*env)->ReleaseStringUTFChars(env, file, str);

  89.     return rst < 0 ? JNI_FALSE : JNI_TRUE;
  90. }

  91. /*
  92.  * Class: JniInterface
  93.  * Method: callbackDestroy
  94.  * Signature: ()V
  95.  */
  96. JNIEXPORT void JNICALL Java_JniInterface_callbackDestroy
  97.   (JNIEnv *env, jclass cls)
  98. {
  99.     s_env = NULL;
  100.     //(*env)->DeleteGlobalRef(env, s_env);
  101.     (*env)->DeleteGlobalRef(env, s_class);
  102.     callback_destroy(s_callBackBody);
  103.     s_callBackBody = NULL;
  104. }

最后将 call_back.c 和 JniInterface.c 编译为 libcallback.so, 再执行 Java文件即可,简单Makefile, 其中的路径【/usr/java/default/include/】 和 【/usr/java/default/include/linux】需要修改为系统对应的jdk路径:

 

点击(此处)折叠或打开

  1. .PHONY: clean
  2. libcallback.so: call_back.o JniInterface.o
  3. gcc -Wall -fPIC -rdynamic -shared -o $@ $^
  4. %.o: %.c
  5. gcc -Wall -c -o $@ -I./ -I/usr/java/default/include/ -I/usr/java/default/include/linux $(filter %.c, $^)
  6. clean:
  7. -rm *.so *.o
执行结果如下:

 

点击(此处)折叠或打开

  1. [tester@dellquad JavaCallC]$ export LD_LIBRARY_PATH=.
  2. [tester@dellquad JavaCallC]$ make
  3. gcc -Wall -c -o call_back.o -I./ -I/usr/java/default/include/ -I/usr/java/default/include/linux call_back.c
  4. gcc -Wall -c -o JniInterface.o -I./ -I/usr/java/default/include/ -I/usr/java/default/include/linux JniInterface.c
  5. gcc -Wall -fPIC -rdynamic -shared -o libcallback.so call_back.o JniInterface.o
  6. [tester@dellquad JavaCallC]$ javac JniInterface.java
  7. [tester@dellquad JavaCallC]$ java JniInterface
  8. [Info]: totalLine = 110 codeLine = 80 modifyTime = [2013-05-10 12:15:43] fileName = /home/vincent/call_back.c
  9. [Info]: totalLine = 210 codeLine = 180 modifyTime = [2013-05-10 12:15:48] fileName = /home/vincent/call_back.c
  10. [Info]: totalLine = 310 codeLine = 280 modifyTime = [2013-05-10 12:15:53] fileName = /home/vincent/call_back.c
  11. [Info]: totalLine = 410 codeLine = 380 modifyTime = [2013-05-10 12:15:58] fileName = /home/vincent/call_back.c
  12. [Info]: totalLine = 510 codeLine = 480 modifyTime = [2013-05-10 12:16:03] fileName = /home/vincent/call_back.c
  13. [Info]: totalLine = 610 codeLine = 580 modifyTime = [2013-05-10 12:16:08] fileName = /home/vincent/call_back.c
  14. [Info]: totalLine = 710 codeLine = 680 modifyTime = [2013-05-10 12:16:13] fileName = /home/vincent/call_back.c
  15. [Info]: totalLine = 810 codeLine = 780 modifyTime = [2013-05-10 12:16:18] fileName = /home/vincent/call_back.c
  16. [Info]: totalLine = 910 codeLine = 880 modifyTime = [2013-05-10 12:16:23] fileName = /home/vincent/call_back.c
  17. [Info]: totalLine = 1010 codeLine = 980 modifyTime = [2013-05-10 12:16:28] fileName = /home/vincent/call_back.c
  18. [Info]: totalLine = 1110 codeLine = 1080 modifyTime = [2013-05-10 12:16:33] fileName = /home/vincent/call_back.c
  19. [Info]: totalLine = 1210 codeLine = 1180 modifyTime = [2013-05-10 12:16:38] fileName = /home/vincent/call_back.c
  20. [Info]: totalLine = 1310 codeLine = 1280 modifyTime = [2013-05-10 12:16:43] fileName = /home/vincent/call_back.c
  21. [Info]: totalLine = 1410 codeLine = 1380 modifyTime = [2013-05-10 12:16:48] fileName = /home/vincent/call_back.c
  22. [Info]: totalLine = 1510 codeLine = 1480 modifyTime = [2013-05-10 12:16:53] fileName = /home/vincent/call_back.c
  23. [Info]: totalLine = 1610 codeLine = 1580 modifyTime = [2013-05-10 12:16:58] fileName = /home/vincent/call_back.c
  24. [Info]: totalLine = 1710 codeLine = 1680 modifyTime = [2013-05-10 12:17:03] fileName = /home/vincent/call_back.c
  25. [Info]: totalLine = 1810 codeLine = 1780 modifyTime = [2013-05-10 12:17:08] fileName = /home/vincent/call_back.c
  26. [Info]: totalLine = 1910 codeLine = 1880 modifyTime = [2013-05-10 12:17:13] fileName = /home/vincent/call_back.c

  27. [tester@dellquad JavaCallC]$

代码:上传JavaCallC.tar.bz2 说不支持该类型文件,改成了 JavaCallC.tar.bz2.txt 上传,下载后改回来即可。
JavaCallC.tar.bz2.txt



阅读(1874) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~