添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have an issue. I'm calling a test function that gets a number of bytes from a Java import function and then returns that data as an array of shorts. At the moment I'm getting a problem that the program crashes with indirect reference. My code is this:

#define AR_LEN  8
JNIEXPORT jshortArray JNICALL Java_com_example_datafeed_DataFeed_decode
    (JNIEnv *env, jobject obj) {
    int out_size = 0;
    int i, frame_count;
    short  *data;          /* data stream               */
    int shutdown = 1;
    jbyte *temp;
    short data_btes = AR_LEN *2;
    jshortArray j_out_data;
   // This gets the java class references
    jclass cls = (*env)->FindClass(env, "com/example/datafeed/DataFeed");
    jmethodID getbytes = (*env)->GetMethodID(env, cls, "getBytes", "(I)[B");
    jmethodID outputMethod = (*env)->GetMethodID(env, cls, "playData", "([S)V");
   // Set up a return array
    j_out_data = (*env)->NewShortArray(env, AR_LEN);
    data = malloc(AR_LEN * 2 + 2);
    while(shutdown != 0) {
        __android_log_print(ANDROID_LOG_ERROR, "Native", "Calling Method %d", data_btes);
        // Call the java method to return byte array
        jbyteArray getbytes_ret = (*env)->CallObjectMethod(env, obj, getbytes, data_btes);
        // check for returned data
        __android_log_print(ANDROID_LOG_ERROR, "Native", "Returned %p %d", temp, getbytes_ret);
       //Get the array elements.  This line seems to crash
        temp = (*env)->GetByteArrayElements(env, getbytes_ret, 0);
        __android_log_print(ANDROID_LOG_ERROR, "Native", "Array Set");
        memcpy(data, temp, data_btes);
        __android_log_print(ANDROID_LOG_ERROR, "Native", "Memory Copied");
       // Delete the referece to temp
        (* env)->DeleteLocalRef(env,temp);
        if(temp == NULL)  {
            shutdown = 0;
        } else {
           // Set the Array of shorts
            (*env)->SetShortArrayRegion(env,j_out_data, 0, AR_LEN, data);
    // Call the return method
         (*env)->CallObjectMethod(env, obj, outputMethod, j_out_data);
    (* env)->DeleteLocalRef(env,outputMethod);
    (* env)->DeleteLocalRef(env,j_out_data);

When I run this code I get this output:

E/Native(18292): Calling Method 16
D/FEED(18292): getting 16 bytes
D/FEED(18292): returning 16 bytes  
E/Native(18292): Returned 
E/Native(18292): Array Set
E/Native(18292): Memory Copied
W/dalvikvm(18292): JNI WARNING: DeleteLocalRef(0x42e06ac0) failed to find entry
D/OUTPUT(18292): recieved 8 data
E/Native(18292): Calling Method 0x6ded7770 16
E/Native(18292): Returned 
W/dalvikvm(18292): Invalid indirect reference 0x8 in decodeIndirectRef
I/dalvikvm(18292): "Thread-55890" prio=5 tid=11 RUNNABLE
I/dalvikvm(18292):   | group="main" sCount=0 dsCount=0 obj=0x42e06520 self=0x75221628
I/dalvikvm(18292):   | sysTid=18308 nice=0 sched=0/0 cgrp=apps handle=1965187080
I/dalvikvm(18292):   | state=R schedstat=( 0 0 0 ) utm=0 stm=0 core=0
I/dalvikvm(18292):   at com.example.datafeed.DataFeed.decode(Native Method)
I/dalvikvm(18292):   at com.example.datafeed.DataFeed.run(DataFeed.java:68)
I/dalvikvm(18292):   at java.lang.Thread.run(Thread.java:841)
E/dalvikvm(18292): VM aborting
A/libc(18292): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 18308 (Thread-55890)
I/DEBUG(17442): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG(17442): Build fingerprint: 'samsung/jfltexx/jflte:4.3/JSS15J/I9505XXUEMK9:user/release-keys'
I/DEBUG(17442): Revision: '11'
I/DEBUG(17442): pid: 18292, tid: 18308, name: Thread-55890  >>> com.example.datafeed <<<
I/DEBUG(17442): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
I/DEBUG(17442):     r0 00000000  r1 00000000  r2 00000000  r3 40b76e50
I/DEBUG(17442):     r4 deadd00d  r5 0000020c  r6 752342dc  r7 752342e3
I/DEBUG(17442):     r8 75336b38  r9 75225fb8  sl 75221638  fp 75336b4c
I/DEBUG(17442):     ip 47844001  sp 753368b8  lr 00000001  pc 40afd970  cpsr 60000030
01-17 10:57:55.342: I/DEBUG(17442):     d0  0000000000000000  d1  0000000000000000
01-17 10:57:55.342: I/DEBUG(17442):     d2  0000000000000000  d3  0000000000000000
01-17 10:57:55.342: I/DEBUG(17442):     d4  0010010200000010  d5  000000010000009c
01-17 10:57:55.342: I/DEBUG(17442):     d6  ffffffffffffffff  d7  3f8000003f800000
01-17 10:57:55.342: I/DEBUG(17442):     d8  0000000000000000  d9  0000000000000000
01-17 10:57:55.342: I/DEBUG(17442):     d10 0000000000000000  d11 0000000000000000
01-17 10:57:55.342: I/DEBUG(17442):     d12 0000000000000000  d13 0000000000000000
01-17 10:57:55.342: I/DEBUG(17442):     d14 0000000000000000  d15 0000000000000000
01-17 10:57:55.342: I/DEBUG(17442):     d16 6e616c2e6176616a  d17 6461657268542e67
01-17 10:57:55.342: I/DEBUG(17442):     d18 002e006300650073  d19 00700069006c0063
01-17 10:57:55.342: I/DEBUG(17442):     d20 00720061006f0062  d21 00430049002e0064
01-17 10:57:55.342: I/DEBUG(17442):     d22 006200700069006c  d23 006400720061006f
01-17 10:57:55.342: I/DEBUG(17442):     d24 ff00550055005500  d25 ff00550055005500
01-17 10:57:55.342: I/DEBUG(17442):     d26 ff00550055005500  d27 ff00550055005500
01-17 10:57:55.342: I/DEBUG(17442):     d28 ff00550055005500  d29 ff00550055005500
01-17 10:57:55.342: I/DEBUG(17442):     d30 0000000d000d000d  d31 0000000d000d000d
01-17 10:57:55.352: I/DEBUG(17442):     scr 60000010
01-17 10:57:55.352: I/DEBUG(17442): backtrace:
01-17 10:57:55.352: I/DEBUG(17442):     #00  pc 00048970  /system/lib/libdvm.so (dvmAbort+67)
01-17 10:57:55.352: I/DEBUG(17442):     #01  pc 0004d41b  /system/lib/libdvm.so (dvmDecodeIndirectRef(Thread*, _jobject*)+146)
01-17 10:57:55.352: I/DEBUG(17442):     #02  pc 0004e141  /system/lib/libdvm.so
01-17 10:57:55.352: I/DEBUG(17442):     #03  pc 00000cf3  /data/app-lib/com.example.datafeed-1/libdatafeed.so (Java_com_example_datafeed_DataFeed_decode+194)
01-17 10:57:55.352: I/DEBUG(17442):     #04  pc 0002048c  /system/lib/libdvm.so (dvmPlatformInvoke+112)
01-17 10:57:55.352: I/DEBUG(17442):     #05  pc 00050ff3  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
01-17 10:57:55.352: I/DEBUG(17442):     #06  pc 00052ca9  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+256)
01-17 10:57:55.352: I/DEBUG(17442):     #07  pc 00029920  /system/lib/libdvm.so
01-17 10:57:55.352: I/DEBUG(17442):     #08  pc 0002e2ec  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
01-17 10:57:55.352: I/DEBUG(17442):     #09  pc 00063179  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+292)
01-17 10:57:55.352: I/DEBUG(17442):     #10  pc 000631a3  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
01-17 10:57:55.352: I/DEBUG(17442):     #11  pc 00057f03  /system/lib/libdvm.so
01-17 10:57:55.352: I/DEBUG(17442):     #12  pc 0000cc60  /system/lib/libc.so (__thread_entry+72)
01-17 10:57:55.352: I/DEBUG(17442):     #13  pc 0000cddc  /system/lib/libc.so (pthread_create+208)

I notice that the java method is only being called once, despite CallObjectMethod being called twice (it prints the returned output, despite not printing the debug method from the java code). Not sure how to solve this, do I have to reset the reference ever time? If anyone has any suggestions will be much appreciated.

Edit: Not sure if this will help, but I've added the java code.

public class DataFeed {
    static {
        System.loadLibrary("datafeed");
    private BlockingQueue<Byte> inputQueue;
    public DataFeed () {
        inputQueue=new LinkedBlockingQueue<Byte>();
public native void decode();
public byte[] getBytes (int bytes)  {
    int curbyte = 0;
    byte[] retbytes = new byte[bytes];
    Log.d("FEED", "getting " + bytes + " bytes");
    while(curbyte < bytes) {
        try {
            retbytes[curbyte] = inputQueue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        curbyte ++;
    Log.d("FEED", "returning " + retbytes.length + " bytes  ");
    return retbytes;
    public void playData(short[] outdata) {
        Log.d("OUTPUT", "recieved " + outdata.length + " data");

When calling GetByteArrayElements you should release pointer with ReleaseByteArrayElements not DeleteLocalRef. ex:

int fLen = env->GetArrayLength(getbytes_ret);
jbyte *temp = (jbyte *)(*env)->GetByteArrayElements(env, getbytes_ret, NULL);
__android_log_print(ANDROID_LOG_ERROR, "Native", "Array Set"); 
memcpy(data, temp, fLen );
__android_log_print(ANDROID_LOG_ERROR, "Native", "Memory Copied");
(*env)->ReleaseByteArrayElements(env, getbytes_ret, temp, 0 );
                Ok thanks, changed that.  Still having the same issue as before though :(.  Pretty sure its an issue with failing to cal the java method properly the 2nd time, which is strange because the first call goes through fine
– user2783377
                Jan 17, 2014 at 11:42
                You dont need to call DeleteLocalRef on GetMethodID result, I think you should start with something small and once no errors appear start adding more calls - you will see what is causing your problems. In above logcat its clearly DeleteLocalRef.
– marcinj
                Jan 17, 2014 at 11:46
                I don't think so, because after using the the ReleaseByteArrayElements I'm not calling the DeleteLocalRef at all in the main loop.  I'll try to slim it down a bit though and see where i get.  Thanks
– user2783377
                Jan 17, 2014 at 11:56
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.