LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3267|回复: 6

Debian 下使用kaffe进行JNI的编程

[复制链接]
发表于 2005-12-14 15:36:54 | 显示全部楼层 |阅读模式
SUN java JNI示例的Debian Kaffe版本
首先安装kaffe,apt-get install kaffe。
准备HelloWorld.java文件

  1. class HelloWorld {
  2.     public native void displayHelloWorld();

  3.     static {
  4.         System.loadLibrary("hello");
  5.     }
  6.    
  7.     public static void main(String[] args) {
  8.         new HelloWorld().displayHelloWorld();
  9.     }
  10. }
复制代码

使用javac命令
~#javac HelloWorld.java
得到了HelloWorld.class文件。
使用javah命令
~#javah HelloWorld
出错,提示没有设置CLASSPATH
~#export CLASSPATH=/usr/lib/kaffe/jre/lib
再次运行javah命令,提示打开对象HelloWorld失败。
~#javah -classpath /usr/share/kaffe/Klasses.jar:. HelloWorld
得到了HelloWorld.h文件
后面就是C语言出场的时候了,dang dangdang dang!:cool:
HelloWorldImp.c文件

  1. #include "HelloWorld.h"
  2. #include <stdio.h>

  3. JNIEXPORT void JNICALL
  4. Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
  5. {
  6.     printf("Hello world!\n");
  7.     return;
  8. }
复制代码

将它编译成动态链接库
~#gcc HelloWolrdImp.c -shared -o libhello.so
设置LD_LIBRARY_PATH为当前目录
~#export LD_LIBRARY_PATH=`pwd`
只剩下最后一步,运行HelloWorld
~#java -classpath /usr/share/kaffe/Klasses.jar:. HelloWorld
成功了,呵呵
发表于 2005-12-16 12:54:59 | 显示全部楼层
据说gcc自已的CNI更直观方便。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-12-19 09:13:56 | 显示全部楼层
Post by acguy
据说gcc自已的CNI更直观方便。

CNI主要是给C++使用JAVA的机会,而JNI主要是给JAVA使用C++的机会。这个是我粗浅的理解,不知道对不对。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-12-26 10:38:59 | 显示全部楼层

如果要把HelloWorld.class的main和native方法放在客户文件和库文件要怎么做??

更改HelloWorld.java文件

  1. package hello;

  2. public class HelloWorld {
  3.    
  4.     static {
  5.         System.loadLibrary("hello");
  6.     }
  7.          
  8.     public native void displayHelloWorld();
  9. }
复制代码

编译之
javac -d . HelloWorld.java
自动会在当前目录下创建hello目录,在hello目录下有HelloWorld.class文件
让javah创建c所需头文件
javah hello/HelloWorld
在当前目录下得到了hello_HelloWorld.h文件
让我们看一下hello_HelloWorld.h文件的内容

  1. #include <jni.h>

  2. #ifndef _Included_hello_HelloWorld
  3. #define _Included_hello_HelloWorld

  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif

  7. JNIEXPORT void JNICALL Java_hello_HelloWorld_displayHelloWorld(JNIEnv*, jobject);

  8. #ifdef __cplusplus
  9. }
  10. #endif

  11. #endif
复制代码

创建客户文件HelloWorldClinet.java文件

  1. import hello.HelloWorld;

  2. public class HelloWorldClient{
  3.      public static void main(String[] args) {
  4.         new HelloWorld().displayHelloWorld();
  5.     }
  6. }
复制代码

编译之
javac HelloWorldClient.java
得到HelloWorldClinet.class文件

这时候轮到主角C出场了,呵呵

  1. #include "hello_HelloWorld.h"
  2. #include <stdio.h>

  3. JNIEXPORT void JNICALL
  4. Java_hello_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
  5. {
  6.     printf("Hello world!\n");
  7.     return;
  8. }
复制代码

命名为HelloWorldImp.c。
编译之
gcc HelloWorldImp.c --shared -o libhello.so
重新设置LD_LIBRARY_PATH
export LD_LIBRARY_PATH=`pwd`
如此运行java HelloWorldClinet
请注意整个攻略中,应该将CLASSPATH设置为.:/usr/lib/kaffe/jre/lib/rt.jar:/usr/lib/kaffe/jre/lib/tools.jar
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-3-11 14:03:27 | 显示全部楼层
想不到当年预言的java+c的编程趋势,现在在android SDK+NDK的今天得以实现。
回复 支持 反对

使用道具 举报

发表于 2010-3-18 02:52:20 | 显示全部楼层
~#java -classpath /usr/share/kaffe/Klasses.jar:. HelloWorld

这一行运行的应该是 HelloWorld.class 文件,所以之前的所有工作都是自歁欺人。

如果你运行的c编译出来的,我想应该使用./HelloWorld 来运行。

JNI 是为了让Java代码调用系统库,如linux下so,win下的dll等。

kaffe 十几前的东西,java 1时代的产物,java 2 开始,sun开始修改协议,以保证jvm的兼容性,这些山寨项目都夭折了。。。
回复 支持 反对

使用道具 举报

发表于 2010-3-18 09:16:06 | 显示全部楼层
现在的kaffe还可以,跑跑swing什么的没问题,就是功能少了点。主要是现在开源的兼容虚拟机都在用GNU Classpath,兼容性比以前要好一些了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表