3

JNI から Android にデータのブロックを送信したい。

jchar*JNI でを作成し、データを入力して、Android に として返しましたjcharArray。しかし、アンドロイドでデータを表示している間、それはジャンク値になります。

これは私の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]));

誰でも間違いを指摘できますか?長い間苦労..

4

2 に答える 2

4

以下は、作業中のものに似たコードです。
この例では、配列内のオブジェクトが UTF 文字列である jobjectArray が Java に返されます。

ネイティブ コード: 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");
    }
}
于 2012-08-14T18:16:34.203 に答える
0

JNIでNewCharArrayを作成する方法を理解するために誰かがこれに出くわした場合、できません..代わりに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[] 引数を送信するとは思わない...ただし、これはうまくいくと信じています。

//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"));
于 2013-03-25T18:29:51.200 に答える