从本机代码调用java方法时,如何解决传递给JNI错误的错误全局或本地引用

时间:2018-03-16 05:26:57

标签: java java-native-interface

我搜索了这个问题的许多答案,但没有一个似乎与我的情况相符。我无法弄清楚我在哪里犯错误。我在java中创建一个本机方法并通过jni调用它。在本机方法中我得到一个java类方法的引用并从那里调用它

我的java类如下:

import java.util.ArrayList ; 
import java.util.LinkedHashMap ; 

public class WmiClientClassJson {

    static {
        System.load("C:\\Users\\vignesh-pt1616\\Desktop\\WmiClientLibraryJson\\Debug\\WmiClientLibraryJson.dll");
    }

    public native void createConnection(String query , LinkedHashMap<String,Object> map , ArrayList<LinkedHashMap<String,Object>> list);

    public static void main(String[] args)
    {
        WmiClientClassJson obj = new WmiClientClassJson(); 
        LinkedHashMap<String , Object> map = new LinkedHashMap<String , Object>(); 
        ArrayList<LinkedHashMap<String , Object>> list= new ArrayList<LinkedHashMap<String , Object>>();
        obj.createConnection("String" , map , list );
    }

    public void indexToEs()
    {
        System.out.println("index method called");
    }
}

我已经生成了放在指定目录中的dll库。我的本机方法实现如下。

JNIEXPORT void JNICALL Java_WmiClientClassJson_createConnection(JNIEnv *env, jobject classobj , jstring query , jobject mmapobj , jobject listobj )
{

    //Getting ListClass reference
    jclass ListClass = env->GetObjectClass(listobj);
    if( ListClass == NULL )
    {
        cout << "ListClass null " << endl ; 
        return ;
    }

    jmethodID listConstructor = env->GetMethodID(ListClass,"<init>","()V");
    if(listConstructor == NULL)
    {
        cout << "mapconstructor null "<< endl ; 
        return ; 
    }
    cout<< "list constructor found" << endl ; 

    //Getting ArrayList add method 
    jmethodID addMethod = env->GetMethodID(ListClass , "add" , "(Ljava/lang/Object;)Z");
    if(addMethod == NULL)
    {
        cout << "addMethod null "<< endl ; 
        return ; 
    }
    //cout << "add method found " << endl ; 

    jmethodID sizeMethod = env->GetMethodID(ListClass , "size" , "()I");
    if(sizeMethod == NULL )
    {
        cout << "sizeMethod null" << endl ; 
        return ; 
    }
    cout << "size method found" << endl ; 

    jclass callingClass = env->GetObjectClass(classobj);
    if( callingClass = NULL )
    {
        cout << "Calling class null " << endl ; 
        return ; 
    }
    else cout << "calling class found" << endl ;

    jmethodID indexMethod = env->GetMethodID(callingClass , "indexToEs" , "()V"); // the code throws an error at this point
    if( indexMethod == NULL )
    {
        cout << "index method not found" << endl ;
        return ;  
    }
    else cout << "index method found" << endl ;
}

当我尝试获取indexToEs方法的方法id时,我将错误的全局或本地引用传递给JNI错误

WARNING: JNI local refs: zu, exceeds capacity: zu
        at java.lang.System.initProperties(Native Method)
        at java.lang.System.initializeSystemClass(Unknown Source)
WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod
list constructor found
size method found
calling class found
FATAL ERROR in native method: Bad global or local ref passed to JNI
        at WmiClientClassJson.createConnection(Native Method)
        at WmiClientClassJson.main(WmiClientClassJson.java:17)

请帮我解决这个问题。谢谢。

1 个答案:

答案 0 :(得分:0)

if( callingClass = NULL )

将采用类引用并将其更改为 0

你应该更多地关注编译器警告,通常C ++编译器提醒你永远不要写

if ( something = 0 )

修复是写

if( callingClass == NULL )