以下は、作業中のものに似たコードです。
この例では、配列内のオブジェクトが 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");
}
}