Java Android JNI字符串问题
JAVA_代码:Java Android JNI字符串问题,java,android,c,java-native-interface,Java,Android,C,Java Native Interface,JAVA_代码: public class Employee { private int age; private String name; public Employee(int age, String name) { this.age = age; this.setName(name); } public int getAge() {
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;
}
我可以设置年龄字段,但设置名称失败。我的代码怎么了
它不起作用,请参见下面的日志
I/DEBUG(31):构建指纹:“generic/google_sdk/generic/:2.2/FRF91/43546:eng/testkeys”
I/DEBUG(31):pid:330,tid:330>>>com.example.jni您需要创建并传递一个JavaString
对象(Ljava/lang/String;)
,而不是本机字符串。
这里是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);
}
每当您看到错误地址0xdeaddood时,您就知道VM故意中止(调用DVMAPort):
I/DEBUG(31):信号11(SIGSEGV),故障地址deadd00d
因此,如果您在日志中查看它,您应该会看到它打印了一个中止的原因
如果您正在编写JNI,那么还应该使用CheckJNI:您没有提到为什么必须为此使用JNI。但是如果性能很重要,你应该考虑直接设置字段,避免通过调用< CallVoidMethod > <代码>在原生模式和java模式之间来回切换。如果将字符串作为输入参数传递给函数,则没有问题,但是字符串是类的私有参数,那么我如何访问它并用值更新它呢
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);
}