这次来介绍一下,带参数和返回值的jni调用。
因为c的int你无法知道他是多少位的,可能16可能32,当然,在java平台上int总是32位的。基于这个原因,java本地接口定义了jint、jlong等类型。
boolean = jboolean 字节为1
byte = jbyte 字节为1
char = jchar 字节为2
.....
在头文件jni.h中,这些类型被typedef语句声明为在目标平台上等价的类型。该头文件也定义了常量JNI_FALSE=0,JNI_TRUE=1。
所以,当你在java层传入的int, long等类型,经过javah的转换,到下面都以
jint,
jlong的形势展现。
这里面,还有一个很常用的类型需要单独考虑,那就是string类型。
在Java中,字符串是
UTF-16编码点的序列,而c的字符串则是以null结尾的字节序列,所以这两种语言中的字符串差别很大。
Java本地接口有两组操作字符串的函数,一组把java字符串转换成“改良的UTF8”字节序列,另一组将他们转化成UTF-16数值的数组,也就是说转换成jchar数组。
JNI函数有一个有些古怪的调用约定,下面是对NewStringUTF函数的一个调用:
JNIEXPORT jstring JNICALL Java_HelloNative_getGreeting(JNIEnv* env, jclass cl){
jstring jstr;
char greeting[] = "Hello, Native World\n";
jstr = (*env)->NewStringUTF(env, greeting);
return jstr;
}
所有对JNI函数的调用都引用到了env指针,该指针是每一个本地方法的第一个参数。env指针是函数指针表的指针。所以,你必须在每个JNI调用前面加上
(*env)->,以便实际上取消对函数指针的引用。而且,env是每个JNI函数的第一个参数。
(C++注意: C++中队JNI函数的访问要简单一些。JNIEnv类的C++版本有一个内敛成员函数,它负责帮你查找函数指针,例如,你可以这样调用NEWStringUTF函数:
jstr = env->NewStringUTF(greeting);
注意,这里从该调用的参数列表里删除了JNIEnv指针。
)
接着string编码来看,两种编码的jstring编码方法,使用两个函数来得到:
NewStringUTF(JNIEnv* env, const char bytes[])和
newString(JNIEnv* env, const jchar chars[], jsize length)。
而
getStringUTF(当然UTF-16对应的是
const jchar* getStringChars()方法,后面的方法就不一一对应了,可以查资料找到)函数可以用来读取一个jstring对象的内容。该函数返回指向描述字符串的“改良UTF-8”字符的const jbyte*指针。注意,具体的
虚拟机可以自由地选择该编码来表示它内部的字符串,所以,你也许可以得到实际的JAVA字符串的字符指针。因为Java字符串是不可变的,所以慎重处理const很重要,不要试图将数据写到该字符数组中。不过,如果虚拟机使用UTF-16或UTF-32字符作为其内部字符串的表示,那么该函数会分配一个新的内存块来存储等价的“改良UTF-8”编码字符。
还有一个问题,虚拟机必须知道你何时使用完字符串,这样它就能进行垃圾回收(垃圾回收器是在一个独立线程中运行的,它能够中断本地方法的执行)。所以,我们必须调用RealeaseStringUTFChars函数。
另外,可以通过调用
GetStringRegion或
GetStringUTFRegion方法来提供你自己的缓存,来存放字符串的字符。
最后
GetStringUTFLength函数返回编码字符串所需的“改良UTF-8”字符个数。
书上有例子,有api,网上也能查到,剩下的方法就不多说了,下次分析一下这两个编码方式吧。
分享到:
相关推荐
调用iphlpapi获得本地ip信息,C++源代码演示获取ip信息的全过程。
通过本地方法调用来调用C语言的例子,一个调用时间的,谨供参考
Android中调用js方法及js中调用本地方法,简单明了
注,chrome 通过注册表注册表 只能调用本地的 exe 或者bat文件,不能调用 ppt word 这样的问题,所以我用VB 写了一个exe 可以接收调用参数,这样只许注册一次就可以通过传参打开所有课执行文件了 由于1.exe是后台...
JS和Android本地方法之间的调用
【方法】html调用本地python程序进行交互 前后端交互
java调用本地打印机java调用本地打印机java调用本地打印机java调用本地打印机
web调用本地应用程序
Apple在北京时间2014年6月3日凌晨发布了iOS8。这次更新在界面上看上去几乎没有修改,不过对于开发者,iOS8...本资源使用SWIFT实现了JS调用本地代码的2中方式,第二种方式是iOS8的新增SDK 本资源在XCode 6 beta 5中开发
js通过webview调用android的本地方法,避免addJavascriptInterface问题
JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式 )。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各...
jni本地调用4
delphi编程实现调用本地程序,本实例可调用本地 截图工具、步骤记录器、画图工具、计算器、记事本、屏幕键盘、放大镜、任务管理器、命令提示符、控制面板、word和excel,用的是WinExec和ShellExecute方法,需要实现...
1、Dubbo 远程调用实现 2、内带zookeeper-3.4.5消息服务 3、直接导入myeclipse运行:dubbo-server导入tomcat中运行 4、dubbo-client 运行测试类/dubbo-client/src/com/fengjx/main/Consumer.java
借助WebSocket完成Android本地代码调用JavaScript代码的插件,并且可以获得返回值
该文档详细介绍了在Java代码中如何调用C或C++代码。主要思想是:将C或C++代码大包成动态链接库,然后共Java代码在执行时调用。
本地摄像头调用api
本地调用外部WebService接口 需要本人另外一个资源:WSDL2Java.zip(根据wsdl生成Java客户端)