4

I m trying to do addition of two 2D Array with the use of jni with an android activity. in the android main activity class i make an object of class sample.java. And pass the field of sample class instance to the native code for addition. the sample.java as follows

    package com.cdacb.mars.ntvoperation;

    public class Sample {

        public int[][] array1;
        public int[][] array2;
        public int[][] array3;
    }

the definition for native code is :

JNIEXPORT void JNICALL
Java_com_cdacb_mars_ntvoperation_Operation_int2dAddition
(JNIEnv *env,jobject this,jobject object ){

            jclass class = (*env)->GetObjectClass(env,object);
            if(class==Null){
                printf("Error in finding class");
                return 0;
            }

            jfieldID fid1= (*env)->GetFieldID(env , class ,"array1","[[I");
            if(fid1==Null){
                    printf("Error in finding mat1 field ");
                    return 0;
                }

            jfieldID fid2= (*env)->GetFieldID(env , class ,"array2","[[I");
                if(fid2==Null){
                        printf("Error in finding mat2 field ");
                        return 0;
                    }

            jfieldID fid3= (*env)->GetFieldID(env , class ,"array3","[[I");
                    if(fid3==Null){
                            printf("Error in finding mat3 field ");
                            return 0;
                        }


            jobjectArray arr1= (jobjectArray)(*env)->GetObjectField(env,this,fid1);
            jobjectArray arr2= (jobjectArray)(*env)->GetObjectField(env,this,fid2);
            jobjectArray class= (*env)->NewObjectArray(env,length,Class,NULL);

            for(jint i=0; i<16; i++){
                class[i]=arr1[i]+arr2[i];
            }

            (*env)->SetObjectField(env, this, fid3, class);
  }

the android.mk file is

    LOCAL_PATH := $(call my_dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE    := Ntvoperation
    LOCAL_SRC_FILE  := operation.c

    include $(BUILD_SHARED_LIBRARY)

But when i run thie=s module it generate error in logcat as:

11-06 14:46:35.875: D/dalvikvm(936): Trying to load lib /data/data/com.cdacb.mars.ntvoperation/lib/libNtvoperation.so 0x411e7090
11-06 14:46:35.905: W/dalvikvm(936): No implementation found for native Lcom/cdacb/mars/ntvoperation/Operation;.int2dAddition:(Lcom/cdacb/mars/ntvoperation/Sample;)V
11-06 14:46:35.924: E/AndroidRuntime(936): java.lang.UnsatisfiedLinkError: Native method not found: com.cdacb.mars.ntvoperation.Operation.int2dAddition:(Lcom/cdacb/mars/ntvoperation/Sample;)V
11-06 14:46:35.924: E/AndroidRuntime(936):  at com.cdacb.mars.ntvoperation.Operation.int2dAddition(Native Method)
11-06 14:46:35.924: E/AndroidRuntime(936):  at com.cdacb.mars.ntvoperation.Operation.onCreate(Operation.java:36)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.app.Activity.performCreate(Activity.java:5008)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.os.Looper.loop(Looper.java:137)
11-06 14:46:35.924: E/AndroidRuntime(936):  at android.app.ActivityThread.main(ActivityThread.java:4745)
11-06 14:46:35.924: E/AndroidRuntime(936):  at java.lang.reflect.Method.invokeNative(Native Method)
11-06 14:46:35.924: E/AndroidRuntime(936):  at java.lang.reflect.Method.invoke(Method.java:511)
11-06 14:46:35.924: E/AndroidRuntime(936):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-06 14:46:35.924: E/AndroidRuntime(936):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-06 14:46:35.924: E/AndroidRuntime(936):  at dalvik.system.NativeStart.main(Native Method)

please help me for solve this problem.

my main java class is

        package com.cdacb.mars.ntvoperation;

        import android.R.string;
        import android.os.Bundle;
        import android.app.Activity;
        import android.widget.TextView;



        public class Operation extends Activity {

            private  native void int2dAddition(Sample object);


             String  display=" ";

            @Override
            public void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);
           //     setContentView(R.layout.main);
                TextView screen = new TextView(this);
                Sample tc=new Sample();
                tc.array1=new int[4][4];
                tc.array2=new int[4][4];
                tc.array3=new int[4][4];
               for(int col=0;col<4;col++){
                   for(int row=0;row<4;row++){
                      tc.array1[col][row]=2;
                      tc.array2[col][row]=4;
                      tc.array3[col][row]=0;

                   }
               } 

               int2dAddition(tc);

               for(int col=0;col<4;col++){
                   for(int row=0;row<4;row++){

                      display= display + tc.array3[col][row] +",";

                   }

               }      

               screen.setText(display);
               setContentView(screen);
            }


            static{
                   System.loadLibrary("Ntvoperation");
                   }

        }
kapil Gupta
  • 157
  • 1
  • 2
  • 14
  • What is the Java declaration of the native method? And what class is it in? – user207421 Nov 06 '12 at 09:49
  • 1
    The code looks correct. Do a `nm -gC libNtvoperation.so` and find out whether the symbol for `int2dAddition` is really there. Just a stupid idea, do you have a proper C header file too? – Pavel Zdenek Nov 06 '12 at 10:09
  • check http://mobile.tutsplus.com/tutorials/android/ndk-tutorial/ check the answer in http://stackoverflow.com/a/4468430/1434631 To pass a java object, in your native part you should: 1. Find JavaClassParameter. 2. Find javaMethodTobeCalledInJNI() 3. Call javaMethodTobeCalledInJNI() – Nermeen Nov 06 '12 at 09:47
  • Err, it does contain a package name. – user207421 Nov 06 '12 at 09:49
  • @EJP, yes but wrong class name and method, check the full answer – Nermeen Nov 06 '12 at 09:50
  • sorry for incomplete post.ques is more clear now. – kapil Gupta Nov 06 '12 at 10:00
  • check http://stackoverflow.com/a/4468430/1434631 – Nermeen Nov 06 '12 at 10:04
  • the mentioned tutorial very helping but this is for methods.Do you have any tutorial regarding accessing class fields . – kapil Gupta Nov 06 '12 at 10:20
  • The package name is not missing, which is what you said prior to your edit; you can't know it is wrong when you haven't seen the native method declaration in Java and don't know what class and package it's in; now that the OP has provided that information, it is clear that your initial guess was wrong; and your edit is now just a collection of links, which aren't by themselves an answer, plus a checklist which is essentially meaningless. Not an answer. – user207421 Nov 06 '12 at 11:28
  • I've run into the same problem; I ran nm -gC lib.so to check if my methods were defined and nm returned "no symbols" for my own lib and the libstlport_shared.so runtime library it depends on. The .so libraries are not 0 bytes so the ndk-build script is generating something... what might this mean? @Nunu: did you try nm -gC on your libraries? What was the result? Thanks! – CCJ Jan 07 '13 at 23:33

1 Answers1

5

This issue may be related to C++ function name decoration; if you surround your C++ functions with extern "C" {...} then you should be able to avoid that hassle and JNI should find your native methods. I was having the same issue until I read this thread describing a similar problem but where it was verified that ANSI C native functions worked but C++ threw the native method not found error. Hope this helps, and props to @yellowstonely who provided this suggestion on the linked thread

Community
  • 1
  • 1
CCJ
  • 1,619
  • 26
  • 41