2016-10-03 75 views
1

我试图建立一个本地方法,虽然它看起来运行良好,但我努力理解函数中的字段[* SIG] -澄清有关GetFieldID

jfieldID GetFieldID(JNIEnv *env, jclass clazz, 
    const char *name, const char *sig); 

https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html

例如,我有一个小型Java代码,它使用一个名为“i”的实例变量,所有这种本机方法(名为test)所做的就是将其乘以2.

现在我指的是Java完全参考手册 - 代码就像 -

我的问题是 - 这是什么“I” - fid =(* env) - > GetFieldId(env,cls,“i”,“I”);

当我读到甲骨文documenttion它说 - https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html

对象
的访问字段GetFieldID

jfieldID GetFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig); 

返回字段ID为实例(非静态)域一类。该字段由其名称和签名指定。 GetField和SetField系列访问器函数使用字段ID来检索对象字段。
GetFieldID()会导致未初始化的类被初始化。
GetFieldID()不能用于获取数组的长度字段。应使用GetArrayLength()代替。
LINKAGE:
JNIEnv接口函数表中的索引94。
参数:
env:JNI接口指针。
clazz:一个Java类对象。
名称:以0结尾的已修改UTF-8字符串中的字段名称。
sig:以0结尾的已修改UTF-8字符串中的字段签名。

请问您可能会详细说明该字段“sig”是什么?我无法将“我”与任何东西联系起来。

#include <jni.h> 
#include "NativeDemo.h" 
#include <stdio.h> 

JNIEXPORT void JNICALL Java_NativeDemo_test(JNIEnv *env , jobject obj) 
{ 
    jclass cls; 
    jfieldID fid; 
    jint i; 

    printf("Starting the native method\n"); 

    cls = (*env)->GetObjectClass(env,obj); 
    fid = (*env)->GetFieldId(env,cls,"i", "I"); 
+0

这种性质的JNI方法或字段签名是该方法或字段的'javap -s'命令输出的内容。当有一种工具可以帮助你时,不要试图自己弄清楚。 – EJP

回答

1

请参见下面的Java核心,诉2通道的 “员工” 的例子。 12,由Horstmann和康奈尔在http://www.horstmann.com/corejava.html “id”是该字段的名称,这里是 私人双重工资; Employee类中的 ;其签名(“sig”)或类型,“D”(双)也必须指定。在你的代码中,“I”是整数。 请参阅“类型字段”http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html 一旦获得了jFieldId,它就可以用来修改 字段的值。

/** 
    @version 1.10 1999-11-13 
    @author Cay Horstmann 
*/ 

#include "Employee.h" 
#include <stdio.h> 

JNIEXPORT void JNICALL Java_Employee_raiseSalary(JNIEnv* env, jobject  this_obj, jdouble byPercent) 
{ 
    /* get the class */ 
    jclass class_Employee = (*env)->GetObjectClass(env, this_obj); 

    /* get the field ID */ 
    jfieldID id_salary = (*env)->GetFieldID(env, class_Employee, "salary", "D"); 

    /* get the field value */ 
    jdouble salary = (*env)->GetDoubleField(env, this_obj, id_salary); 

    salary *= 1 + byPercent/100; 

    /* set the field value */ 
    (*env)->SetDoubleField(env, this_obj, id_salary, salary); 
} 
+0

谢谢。这回答了我的问题。 –

2

这里的“I”是原始整数类型的签名。Oracle提供类型签名的表格:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html#wp276

  • ž布尔
  • 乙字节
  • c char字符
  • š短
  • I INT
  • Ĵ长
  • ˚F浮子
  • D双

对于非原始类型,签名是窗体的

  • 大号完全合格的类;

对于数组,[添加。

对于方法,()用于从返回值中分离参数。

+0

谢谢。这回答了我的问题。 –