3

我想将一块数据从 JNI 发送到 android。

jchar*在 JNI 中创建了一个并用我的数据填充它,并将其作为jcharArray. 但是在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]));

谁能指出错误?挣扎了很久。。

4

2 回答 2

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");
    }
}
于 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[] 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"));
于 2013-03-25T18:29:51.200 回答