Jni符号表
本文是之前博客文章
的延续。之前的文章主题是如何利用rust-jni库提供便于java使用的rust jni代码。本文在之前的基础上继续提供后续关于jni符号,或者type的说明。
起因
写rust端代码的时候,如果我们想返回一个java端的对象我们的rust代码大概会按照以下写法(仅为示例,不可运行):
1 |
|
代码的后两行注释说明了一些和本文无关的情况。以上的代码主要是生成java中的StatusMessage对象,这个对象中有两个field,message 和 code。在java端的对应的类型分别为int,String。以上代码就是填充StatusMessage返回给message端。根据jni库的规则(https://docs.rs/jni/0.16.0/jni/),我们需要以下三步
- 定位StatusMessage的class(熟悉java的人应该知道$之后代表内部类)。
- alloc_object 分配内存
- 填充数据
以上三点是使用jni库的步骤。我们现在关心的点是
set_field中的参数代表什么?
根据jni库的文档,set_field有四个参数,第一个参数为class对象,第二个参数为具体filed的名字,第三个为type。第四个为需要具体填充的值。
本文的重点是关心
type到底是什么
本文要解决的问题:type是什么,这里的type该怎么填充?type的填充主要看java端的规定。我们不从这一头看,我们回头去看java端。下面展示一个使用javac -h命令之后我们得到的java头文件。一般来说,我们不需要java头文件,但是我们要写jni,头文件是必须的。
1 | class HelloWorld { |
.h文件
1 | /* DO NOT EDIT THIS FILE - it is machine generated */ |
生成的h文件之中,我们发现有一段注释,只解释Signature。
Signature为函数签名.
签名的格式为 (参数类型)返回值类型
所以参数为String,返回值为String。得到的类型就是示例中的签名样式。
下面给出type的参考表,或者使用专有名词,叫做Type Signatures
Type Signatures | Java Type |
---|---|
Z | boolean |
B | byte |
C | har |
S | short |
I | int |
J | long |
F | float |
D | double |
Lfully-qualified-class | fully-qualified-class |
[ type | type[] |
( arg-types ) ret-type | method type |
解释其中几点 |
- L后面跟的是具体类型的路径 比如String 类型在signatures中就表现为 Ljava/lang/String
- [数组类型
- 最后一行表现的是signatuer的格式
按照以上规则举个例子
1
2
3
4
5
6
函数:
long f (int n, String s, int[] arr);
对应签名
(ILjava/lang/String;[I)J
注意 [ 只有单边。参数之间不间隔,只有具体类型才用;收尾
所以再对应到一开始提到的问题,type该怎么填写
1 | code 对应 StatusMessage 中的 int 类型。所以写 "I" |
再给出一个oracle的文章,它更好,更全面。无论是写rust还是写c/cpp的接口都参考它。
https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html#wp9502
全文完。