2012-08-14 63 views
3

我想發送一個數據塊從JNI到android。如何發送一個字符數組從JNI到android

我在JNI中創建了一個jchar*,並填充了我的數據,並將其作爲jcharArray返回給了android。但是,在Android中顯示數據時,會導致垃圾數值。

這是我的JNI代碼:

JNIEXPORT jcharArray JNICALL Java_com_android_test_dsp_Vread(
     JNIEnv *env, 
     jobject thiz, 
     jint length) 
{ 
    jchar* datatosend; 
    jcharArray ret; 
   ret= (*env)->NewCharArray(env, length); 
   memset(datatosend,1,length); 
   (*env)->SetCharArrayRegion(env, ret, 0, length, datatosend); 
   return ret; 
} 

我的Java代碼:

char[] rxvddata = new rxvddata[length]; 
rxvddata =Vread(length); 
textview.setText("Data1:"+Integer.tostring(rxvddata[0]) + 
    "Data2:"+Integer.tostring(rxvddata[1])); 

任何人都可以指出錯誤了嗎?掙扎很長時間..

+0

'memset'行似乎是線索 - 你能否驗證'datatosend'是否分配了其內存塊? – t0mm13b 2012-08-14 17:15:25

回答

4

以下是一些代碼,是類似於你正在使用。
在此示例中,將jobjectArray返回給Java,其中Array中的對象是UTF字符串。

本地代碼:ExampleNativeJni.c

#include <jni.h> 
#include <android/log.h> 

#define LOG_TAG "AndroidJniExample" 
#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 
#define AUDIO_TRACK_BUFFER_SIZE (48) 

/* 
* Method used to get the audio track language codes from a video file 
*/ 

JNIEXPORT jobjectArray JNICALL Java_com_example_nativeGetAudioTracks (JNIEnv * env, jobject obj, jstring filePath) { 

    // Convert filePath from jstring to null terminated UTF8 string 
    const char *path = (*env)->GetStringUTFChars(env, filePath, 0); 
    if (!path) { 
      LOGE ("ERROR : pathToFile Conversion error in nativeGetAudioTracks"); 
      (*env)->ReleaseStringUTFChars(env, filePath, path); 
      return NULL; 
    } 

    // Each track is 3 chars + a null terminator. 
    // Allows for up to 12 languages. 
    char langCodeHolder[AUDIO_TRACK_BUFFER_SIZE] = {0}; 
    int numTracks = 0; 
    int fd = open(path, O_RDONLY); 
    if (fd > 0) { 
     // get audio track magic through custom FUSE IOCTL handler 
     numTracks = ioctl(fd, GET_AUDIO_TRACKS, &(langCodeHolder[0])); 
     close(fd); 
    } else { 
     LOGE ("ERROR: open(%s) failed in nativeGetAudioTracks", path); 
     (*env)->ReleaseStringUTFChars(env, filePath, path); 
     close(fd); 
     return NULL; 
    } 

    if (numTracks < 0) { 
     LOG("ERROR: Invalid value returned from GET_AUDIO_TRACKS"); 
     (*env)->ReleaseStringUTFChars(env, filePath, path); 
     return NULL; 
    } 

    if (numTracks == 0) { 
     LOG("ERROR: No audio tracks returned"); 
     (*env)->ReleaseStringUTFChars(env, filePath, path); 
     return NULL; 
    } 

    // Instantiate array to hold language codes. 
    jobjectArray langs; 
    const jint langArraySize = numTracks; 
    jclass stringObject = (*env)->FindClass(env, "java/lang/String"); 
    if (stringObject == NULL) { 
     (*env)->ReleaseStringUTFChars(env, filePath, path); 
     return NULL; 
    } 
    langs = (*env)->NewObjectArray(env, langArraySize, stringObject, (*env)->NewStringUTF(env, NULL)); 

    // Extract each 3-letter language code and stuff them into the array. 
    jstring langCode; 
    char* temp = &(langCodeHolder[0]); 
    jint i; 
    for (i = 0; i < langArraySize; i++) { 
     langCode = temp; 
     (*env)->SetObjectArrayElement(env, langs, i, (*env)->NewStringUTF(env, langCode)); 
     temp += 4; 
    } 

    (*env)->ReleaseStringUTFChars(env, filePath, path); 
    return langs; 
} 

Android的JNI代碼:ExampleAndroidJni.java

public class ExampleAndroidJni { 

    private static ExampleAndroidJni sInstance; 
    private static final String TAG = "ExampleAndroidJni"; 

    public static String[] getAudioTracks(final String filePath) { 
     if (sInstance == null) { 
      sInstance = new ExampleJniClient(); 
     } 

     if (filePath == null) { 
      Log.e(TAG, "file path is null"); 
      return null; 
     } 

     final String[] auduioTracks = sInstance.nativeGetAudioTracks(filePath); 
     if (auduioTracks == null || auduioTracks.length == 0) { 
      Log.i(TAG, "No audio tracks returned for : " + filePath); 
     } 

     return auduioTracks; 
    } 

    native String[] nativeGetAudioTracks(String filePath); 

    static { 
     System.loadLibrary("ExampleNativeJni"); 
    } 
} 
0

如果有人偶然發現了這個弄清楚如何創建一個NewCharArray JNI,你不能......你必須改用NewObject(如Akos所說)。以下是如何做到這一點在C++:

這裏, 「SendClass」 是我JCLASS, 「sendMain」 是我jmethod, 「ENV」 是我的JNIEnv

jstring stringOne = env->NewStringUTF("test1"); 
jstring stringTwo = env->NewStringUTF("test2"); 
jobject jobjDet = env->NewObject(SendClass, sendMain, stringOne, stringTwo); 
env->CallStaticIntMethod(SendClass, sendMain, jobjDet); 
env->DeleteLocalRef(stringOne); 
env->DeleteLocalRef(stringTwo); 
//may need to release more resources 

========= =====================

編輯:

我不認爲以前的代碼我寫將發送一個String [] ARG .. 。我確實相信這會起作用,但:

//array size of 3 means [0], [1], [2] 
jobjectArray jobjDet; 
//creates String[3] = "" 
jobjDet = env->NewObjectArray(3, env->FindClass("java/lang/String", env->NewStringUTF("")); 
env->SetObjectArrayElement(jobjDet, 0, env->NewStringUTF("test1")); 
env->SetObjectArrayElement(jobjDet, 1, env->NewStringUTF("test2")); 
env->SetObjectArrayElement(jobjDet, 2, env->NewStringUTF("test3")); 
相關問題