Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3006178
  • 博文数量: 523
  • 博客积分: 11908
  • 博客等级: 上将
  • 技术积分: 5475
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-03 15:50
文章分类

全部博文(523)

文章存档

2019年(3)

2013年(4)

2012年(71)

2011年(78)

2010年(57)

2009年(310)

分类: LINUX

2012-06-20 22:38:57

JNI就是在java中调用非java代码,如果看到native声明的方法,肯定是有jni调用的,其实现是由其他语言写的程序,常用的是c,c++。
1 首先创建一个简单的java类:
Java代码
  1.   
  2. public class Hello   
  3. {   
  4.  static  
  5.  {   
  6.   try  
  7.   {   
  8. //此处即为本地方法所在链接库名   
  9.    System.loadLibrary("hello");   
  10.   }   
  11.   catch(UnsatisfiedLinkError e)   
  12.   {   
  13.    System.err.println( "Cannot load hello library:\n " +   
  14.                                 e.toString() );   
  15.   }   
  16.  }   
  17.  public Hello()   
  18.  {   
  19.  }   
  20. //声明的本地方法   
  21.   public native void SayHello(String strName);   
  22. }   
public class Hello { static { try { //此处即为本地方法所在链接库名 System.loadLibrary("hello"); } catch(UnsatisfiedLinkError e) { System.err.println( "Cannot load hello library:\n " + e.toString() ); } } public Hello() { } //声明的本地方法 public native void SayHello(String strName); }

2 生成 Hello.h

javac Hello.java生成class文件
javah Hello生成hello.h

这个头文件就是根据了jni的规则来生成了native方法在c/c++的声明。下一步就需要新建c/c++文件来实现这里面的方法

3 在与Hello.h相同的路径下创建一个CPP文件Hello.cpp
C++代码
  1. #include "Hello.h"   
  2. JNIEXPORT void JNICALL Java_Hello_SayHello  (JNIEnv * env, jobject arg, jstring instring)   
  3. {   
  4.     const char *str = env->GetStringUTFChars( instring, JNI_FALSE );   
  5.     printf("Hello,%s\n",str);   
  6.     env->ReleaseStringUTFChars( instring, str );   
  7.     return;   
  8. }  
#include "Hello.h" JNIEXPORT void JNICALL Java_Hello_SayHello (JNIEnv * env, jobject arg, jstring instring) { const char *str = env->GetStringUTFChars( instring, JNI_FALSE ); printf("Hello,%s\n",str); env->ReleaseStringUTFChars( instring, str ); return; }
4.编译生成共享库

a. 编译命令,生成Hello.o
g++ -I /usr/lib/jvm/java-6-sun-1.6.0.03/include -I /usr/lib/jvm/java-6-sun-1.6.0.03/include/linux -fPIC -c Hello.cpp
b.生成动态库文件,libhello.so.1.0
g++ -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 Hello.o

接下来将生成的共享库拷贝为标准文件名

cp libhello.so.1.0 libhello.so

最后通知动态链接程序此共享文件的路径。

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

这里用export 加入共享文件的路径,有时候会有点问题,比如:环境变量不会马上更新等等。

还有一个办法,就是直接将libhello.so拷贝到 /usr/lib 或者/lib 等系统库目录下


5.编写一个简单的Java程序来测试我们的本地方法。
Java代码
  1. import Hello;   
  2. import java.util.*;   
  3. public class ToSay   
  4. {   
  5.     public static void main(String argv[])   
  6.     {   
  7.         ToSay say = new ToSay();   
  8.     }   
  9.     public ToSay()   
  10.     {   
  11.         Hello h = new Hello();   
  12.         //调用本地方法向John问好   
  13.         h.SayHello("John");            
  14.     }   
  15. }  
import Hello; import java.util.*; public class ToSay { public static void main(String argv[]) { ToSay say = new ToSay(); } public ToSay() { Hello h = new Hello(); //调用本地方法向John问好 h.SayHello("John"); } }
用javac编译ToSay.java,生成ToSay.class
向执行普通Java程序一样使用java ToSay,我们会看到在屏幕上出现Hello,John

参考:http://watershitter.iteye.com/blog/477615
http://longrenrex.blog.sohu.com/93931899.html
阅读(2216) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~