我想从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 :(得分: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");
}
}
答案 1 :(得分: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"));