Android JNI字符串问题

时间:2011-09-18 19:07:00

标签: java android c java-native-interface

JAVA_CODE:

 public class Employee {
        private int age;
        private String name;

        public Employee(int age, String name) {
            this.age  = age;
            this.setName(name);
        }
        public int getAge() {
            return this.age;
        }
        public void setAge(int age) {
                this.age = age;
        }
        public String getName() {
            return this.name;
        }
        public void setName(String name) {
            this.name = name; 
        }
    }

C结构:

typedef struct Employee_s {
   int age;
   char name[200];
}Employee_t;

JNI代码看:

jint
Java_com_example_cloudonlibtest_CloudOnLibTestActivity_second( JNIEnv* env,
                                                  jobject this, jobject employeeObject)
{
    Employee_t em;
    em.age =418;
    strcpy(em.name, "TheCat");
    jclass employeeClass = (*env)->GetObjectClass(env, employeeObject);
    jmethodID mid = (*env)->GetMethodID(env,employeeClass , "setAge", "(I)V");
    (*env)->CallVoidMethod(env,employeeObject, mid,em.age);
    jmethodID st = (*env)->GetMethodID(env,employeeClass , "setName", "(Ljava/lang/String;)V");
    (*env)->CallVoidMethod(env,employeeObject, st, em.name);
    return 1;
}

我可以设置年龄字段,但未能将名称设置为失败。我的代码有什么问题?


It didn't work see log below
I/DEBUG   (   31): Build fingerprint: 'generic/google_sdk/generic/:2.2/FRF91/43546:eng/test-keys'
I/DEBUG   (   31): pid: 330, tid: 330  >>> com.example.jni <<<
I/DEBUG   (   31): signal 11 (SIGSEGV), fault addr deadd00d
I/DEBUG   (   31):  r0 00000374  r1 0000000c  r2 0000000c  r3 deadd00d
I/DEBUG   (   31):  r4 00000026  r5 80887fc4  r6 00000000  r7 fffe6624
I/DEBUG   (   31):  r8 bed4e8e8  r9 4186bccc  10 4186bcb4  fp 00000000
I/DEBUG   (   31):  ip 808881ec  sp bed4e808  lr afd154c5  pc 8083b162  cpsr 20000030
I/DEBUG   (   31):          #00  pc 0003b162  /system/lib/libdvm.so
I/DEBUG   (   31):          #01  pc 0002cff4  /system/lib/libdvm.so
I/DEBUG   (   31):          #02  pc 0002d11a  /system/lib/libdvm.so
I/DEBUG   (   31):          #03  pc 0002dbf0  /system/lib/libdvm.so
I/DEBUG   (   31):          #04  pc 00000542  /data/data/com.example.jni/lib/libtest-lib.so
I/DEBUG   (   31):          #05  pc 00013974  /system/lib/libdvm.so
I/DEBUG   (   31):          #06  pc 0003de3c  /system/lib/libdvm.so
I/DEBUG   (   31):          #07  pc 00037216  /system/lib/libdvm.so
I/DEBUG   (   31):          #08  pc 000432ec  /system/lib/libdvm.so
I/DEBUG   (   31):          #09  pc 00018714  /system/lib/libdvm.so
I/DEBUG   (   31):          #10  pc 0001e8c4  /system/lib/libdvm.so
I/DEBUG   (   31):          #11  pc 0001d790  /system/lib/libdvm.so
I/DEBUG   (   31):          #12  pc 0005408e  /system/lib/libdvm.so
I/DEBUG   (   31):          #13  pc 0005bde2  /system/lib/libdvm.so
I/DEBUG   (   31):          #14  pc 00018714  /system/lib/libdvm.so
I/DEBUG   (   31):          #15  pc 0001e8c4  /system/lib/libdvm.so
I/DEBUG   (   31):          #16  pc 0001d790  /system/lib/libdvm.so
I/DEBUG   (   31):          #17  pc 00053eec  /system/lib/libdvm.so
I/DEBUG   (   31):          #18  pc 0004072c  /system/lib/libdvm.so
I/DEBUG   (   31):          #19  pc 00034454  /system/lib/libdvm.so
I/DEBUG   (   31):          #20  pc 0002c930  /system/lib/libandroid_runtime.so
I/DEBUG   (   31):          #21  pc 0002d85c  /system/lib/libandroid_runtime.so
I/DEBUG   (   31):          #22  pc 00008c86  /system/bin/app_process
I/DEBUG   (   31):          #23  pc 0000d362  /system/lib/libc.so
I/DEBUG   (   31): 
I/DEBUG   (   31): code around pc:
I/DEBUG   (   31): 8083b140 1861447c 200618a2 e878f7d8 f7d82000 
I/DEBUG   (   31): 8083b150 4808e9e4 6bdb5823 d0002b00 4b064798 
I/DEBUG   (   31): 8083b160 701c2426 ea5cf7d8 0004ce80 fffe4ae0 
I/DEBUG   (   31): 8083b170 fffe801c 00000374 deadd00d b510b40e 
I/DEBUG   (   31): 8083b180 4c0a4b09 447bb083 aa05591b 6b5bca02 
I/DEBUG   (   31): 
I/DEBUG   (   31): code around lr:
I/DEBUG   (   31): afd154a4 b0834a0d 589c447b 26009001 686768a5 
I/DEBUG   (   31): afd154b4 220ce008 2b005eab 1c28d003 47889901 
I/DEBUG   (   31): afd154c4 35544306 d5f43f01 2c006824 b003d1ee 
I/DEBUG   (   31): afd154d4 bdf01c30 0002ae7c 000000d4 1c0fb5f0 
I/DEBUG   (   31): afd154e4 43551c3d a904b087 1c16ac01 604d9004 
I/DEBUG   (   31): 
I/DEBUG   (   31): stack:
I/DEBUG   (   31):     bed4e7c8  00000015  
I/DEBUG   (   31):     bed4e7cc  afd1453b  /system/lib/libc.so
I/DEBUG   (   31):     bed4e7d0  afd405a0  /system/lib/libc.so
I/DEBUG   (   31):     bed4e7d4  afd4054c  /system/lib/libc.so
I/DEBUG   (   31):     bed4e7d8  00000000  
I/DEBUG   (   31):     bed4e7dc  afd154c5  /system/lib/libc.so
I/DEBUG   (   31):     bed4e7e0  0000ccb0  [heap]
I/DEBUG   (   31):     bed4e7e4  afd1450d  /system/lib/libc.so
I/DEBUG   (   31):     bed4e7e8  fffe6624  
I/DEBUG   (   31):     bed4e7ec  80887fc4  /system/lib/libdvm.so
I/DEBUG   (   31):     bed4e7f0  80887fc4  /system/lib/libdvm.so
I/DEBUG   (   31):     bed4e7f4  00000000  
I/DEBUG   (   31):     bed4e7f8  fffe6624  
I/DEBUG   (   31):     bed4e7fc  afd1456b  /system/lib/libc.so
I/DEBUG   (   31):     bed4e800  df002777  
I/DEBUG   (   31):     bed4e804  e3a070ad  
I/DEBUG   (   31): #00 bed4e808  00000001  
I/DEBUG   (   31):     bed4e80c  8082cff9  /system/lib/libdvm.so
I/DEBUG   (   31): #01 bed4e810  00000001  
I/DEBUG   (   31):     bed4e814  8082d11f  /system/lib/libdvm.so
I/BootReceiver(   59): Copying /data/tombstones/tombstone_04 to DropBox (SYSTEM_TOMBSTONE)

3 个答案:

答案 0 :(得分:5)

您需要创建并传递Java String对象(Ljava/lang/String;),而不是本机字符串。 http://java.sun.com/docs/books/jni/html/objtypes.html#4035

答案 1 :(得分:4)

每当你看到0xdeaddood的故障地址时,你就知道VM故意中止(调用dvmAbort):

I / DEBUG(31):信号11(SIGSEGV),故障地址deadd00d

所以,如果你在日志中看到它,你应该看到它打印了一个原因为什么它会中止。

如果你正在编写JNI,你也应该使用CheckJNI:http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html

答案 2 :(得分:0)

这是C上的工作方法。试试这个,如果您有疑问请问......

jclass employeeClass = (*env)->GetObjectClass(env, employeeObject);
jfieldID fid = NULL;
char* ped = "TheCat";
fid = (*env)->GetFieldID(env, employeeClass, "setName", "Ljava/lang/String;");
if( fid != NULL ) {
    jstring myStr = (*env)->NewStringUTF( env, ped);
    // Set "eventData".
    (*env)->SetObjectField(env, enrollClassObject, fid, myStr);
}