java本地方法的学习总结

java语言较之C/C++语言,其带来的优势显而易见,但实际中,有时还是会需要编写或使用其他语言的代码,这 
种代码通常成为本地代码。在java中使用本地代码应用的并不多,使用本地代码的情形一般有三种:
1、在该种语言中,已经有了大量测试过的和调试过的代码,且功能成熟稳定,这时候,若将这些代码移植到
java语言就会显得很费时。
2、java代码通常占内存比较大,有时会降低系统性能,而像 C/C++ 它们的运行效率会高的多,当代码的执行
速度至关重要的时候,可以考虑使用本地代码。
3、如果当前应用程序需要访问系统的各个特性和设备时。
使用了本地代码,应用将丧失可移植性,通常不会去使用本地方法。
一、用java调用C函数
如果要用java调用 C 中的一个函数,那么应遵循如下步骤:
第一步,将该函数封装在一个类中,即在这个类中声明该本地方法,需关键字 native ,它会提醒编译器,该
方法将在外部定义,如下所示;
class NativeMethod
{
public static native void greeting();//本地方法可以是静态的也可以是非静态的;
}
第二步,编写相应的 C 函数,在这里需要注意,必须按照java运行环境预期的那样来命名这个函数,如果类中
含有非ASCII的字母或数字,需用相应的十六进制替换,其实这个工作是繁琐的,而正如我们所预期的,JDK中
提供了一个相应的命令来完成这项工作,可以使用 javah 命名来帮我们自动生成函数名,如下所示:
javac NativeMethod.java
javah NativeMethod
随后它会产生相应的 C 头文件,NativeMethod.h
第三步,将函数原型写到源文件中,如下所示:
#include "NativeMethod.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_NativeMethod_greeting(JNIEnv* env, jclass cl)
{
printf("Hello World!\n");
}
第四步,将本地的 C 代码编译到一个动态装载库中,此步操作依赖于编译器。
最后一步,在定义本地方法的java类中添加一个对System.loadLibrary方法的调用,如:
static
{
System.loadLibrary("NativeMethod");//一般书写在静态方法块中
}
随后就可以在main方法中测试了。
二、数值参数与返回值
1、在C与java编程语言之间传递参数时,由于这两种语言对数字类型的实现不同,所以需要指定他们彼此之间
的对应类型,数据类型之间的对应关系如下
int->jint,long->jlong,byte->jbyte,char->jchar,short->jshort,float->jfloat,double-
>jdouble,boolean->jboolean
2、对于字符串参数,需要考虑编程语言之间的编码方式,java中的字符串是UTF-16编码点的序列,而C的字符
串则是以null结尾的字节序列。java本地接口有两组操作字符串的函数,一组是把java字符串转换成改良的
UTF-8字节序列,另一组将它们转换成UTF-16数值的数组,也就是转换成jchar数组。从C代码访问java字符串常
用的方法有如下几种:
jstring NewStringUTF(JNIEnv* env,const char bytes[])//根据改良的UTF-8字节序列,返回一个新的java字
符串,当字符串无法构造时,返回null
jsize getStringUTFLength(JNIEnv* env,jstring string)//返回进行UTF-8编码所需的字节数
const ibyte* GetStringUTFChars(JNIEnv* env,jstring string,jboolean* isCopy)//返回改良UTF-8编码的
字符串的指针,直到ReleaseStringUTFChars函数调用前该指针一直有效的。
void ReleaseStringUTFChars(JNIEnv* env,jstring string,const ibyte bytes[])//通知虚拟机本地代码不
再需要通过bytes访问Java字符串
void GetStringRegion(JNIEnv * env,jstring string,jsize start,jsize length,jchar *buffer)//将一个
Unicode字符序列从字符串复制到用户提供的缓存中。
void GetStringUTFREdion(JNIEnv * env,jstring string,jsize start,jsize length,jchar *buffer)//将一
个改良的UTF-8字符序列从字符串复制到用户提供的缓存中。
更多方法可查看API文档
3、C调用java一般遵循三个步骤:
1)获取隐式参数的类
2)获取方法ID
3)进行调用
 
posted @ 2013-01-10 17:36  mmy--博客园  阅读(1708)  评论(0编辑  收藏  举报