我们在将字符串从JNI .c代码传递给android时遇到了问题。给出下面的代码
.c代码
char* getSignatureMd5(JNIEnv* env, jobject obj)
{`char * sign = loadSignature(env, obj);`
MD5_CTX context = { 0 };
MD5Init(&context);
MD5Update(&context, (unsigned char*)sign, strlen(sign));
unsigned char dest[16] = { 0 };
MD5Final(dest, &context);
int i;
static char destination[32]={0};
for (i = 0; i < 16; i++) {
sprintf(destination, "%s%02x", destination, dest[i]);
}
return destination;
}
JNIEXPORT jstring JNICALL Java_com_sign_signaturecapturesbi_MainActivity_getToken(JNIEnv *env, jobject obj,
jstring string) {
__android_log_print(ANDROID_LOG_VERBOSE, "MyApp", "inside getToken");
char *signValue = getSignatureMd5(env, obj);
__android_log_print(ANDROID_LOG_VERBOSE, "MyApp", "inside ExceptionCheck if %s", signValue);
char* msg = signValue;
jstring result;
puts(msg);
__android_log_print(ANDROID_LOG_VERBOSE, "MyApp", "msg %s", msg);
result = (*env)->NewStringUTF(env,msg);
return result;
}
Android原生代码
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mJavaText = (TextView) findViewById(R.id.java_sign);
mJniText = (TextView) findViewById(R.id.jni_sign);
// mJavaText.setText("Get token from jni:" + getPackage());
//mJniText.setText("Get token from jni:" + getToken());
try {
String tokenvalue = getSignature();
System.out.println("tokenpackage in android ffi "+ tokenvalue);
mJniText.setText("Get token from jni:" + tokenvalue);
// mJniText.setText("Get token from jni:" + getPackage);
}catch (Exception e) {
// This will catch any exception, because they are all descended from Exception
System.out.println("Error in android ffi "+ e.getMessage());
}
}
static {
System.loadLibrary("check-sign");
}
public native String getToken(String str);
public native String getPackage();
public String getSignature(){ //mJavaText.setText("从jni获取令牌:“+ getPackage());
String valuetoken = getToken("hello");
System.out.println("valuepackage in android ffi "+ valuetoken);
// mJniText.setText("Get token from jni:" + getToken());
return valuetoken;
}
}
但是我在这里得到的错误
JNI在应用程序中检测到错误:JNI NewStringUTF调用未知抛出位置抛出的挂起异常'java.lang.NullPointerException
请帮助我解决这个问题
我尝试使用以下代码。我仍然得到Null指针异常
jstring Java_com_sign_signaturecapturesbi_MainActivity_getToken(JNIEnv *env, jobject obj)
{
__android_log_print(ANDROID_LOG_VERBOSE, "MyApp", "inside signature");
char *signValue = (char*)malloc(50);
strcpy(signValue, getSignatureMd5(env, obj));
jstring result = (*env)->NewStringUTF(env, signValue);
__android_log_print(ANDROID_LOG_VERBOSE, "MyApp", "result if %s", result);
return result;
}
添加了loadSignature方法&amp; jstringTostring方法
char* loadSignature(JNIEnv* env, jobject obj)
{
jclass cls = (*env)->FindClass(env, "android/content/ContextWrapper");
//this.getPackageManager();
jmethodID mid = (*env)->GetMethodID(env, cls, "getPackageManager",
"()Landroid/content/pm/PackageManager;");
if (mid == NULL) {
return "";
}
jobject pm = (*env)->CallObjectMethod(env, obj, mid);
if (pm == NULL) {
return "";
}
//this.getPackageName();
mid = (*env)->GetMethodID(env, cls, "getPackageName", "()Ljava/lang/String;");
if (mid == NULL) {
return "";
}
jstring packageName = (jstring)(*env)->CallObjectMethod(env, obj, mid);
// packageManager->getPackageInfo(packageName, GET_SIGNATURES);
cls = (*env)->GetObjectClass(env, pm);
mid = (*env)->GetMethodID(env, cls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
jobject packageInfo = (*env)->CallObjectMethod(env, pm, mid, packageName, 0x40); //GET_SIGNATURES = 64;
cls = (*env)->GetObjectClass(env, packageInfo);
jfieldID fid = (*env)->GetFieldID(env, cls, "signatures", "[Landroid/content/pm/Signature;");
jobjectArray signatures = (jobjectArray)(*env)->GetObjectField(env, packageInfo, fid);
jobject sign = (*env)->GetObjectArrayElement(env, signatures, 0);
cls = (*env)->GetObjectClass(env, sign);
mid = (*env)->GetMethodID(env, cls, "toCharsString", "()Ljava/lang/String;");
if(mid == NULL){
return "";
}
jstring signString = (jstring)(*env)->CallObjectMethod(env, sign, mid);
return jstringTostring(env, signString);
}
char* jstringTostring(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String");
jstring strencode = (*env)->NewStringUTF(env, "utf-8");
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode);
jsize alen = (*env)->GetArrayLength(env, barr);
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba, 0);
return rtn;
}
答案 0 :(得分:-1)
在使用 NewStringUTF 之前尝试检查NULL。这是我的代码:
...
if (msg == NULL){
return NULL;
}
result = (*env)->NewStringUTF(env,msg);
return result;