サウンドの非同期処理のための java側の関数はできたので、次は native側の処理です。
ただ、今まで java側から nativeを呼ぶことはあっても native側から javaの関数を呼んでいるところはありませんでした。ということで今回はそのあたりの処理を行うのですが、残念ながら他人に説明できるほどきちんと理解はしていませんので、ソースで手順だけ示します。ご容赦を。
SysMain.cpp
JavaVM* g_JavaVM; // JavaVM情報
extern "C"
jint JNI_OnLoad(JavaVM* _vm, void*)
{
g_JavaVM = _vm; // JavaVM保存
JNIEnv* _env;
if ( _vm->GetEnv((void**)&_env, JNI_VERSION_1_6) != JNI_OK ) { // JNIのバージョンチェック
return -1;
}
return JNI_VERSION_1_6;
}
JNI_OnLoadは nativeのライブラリが読み込まれたときに呼ばれる関数です。
引数の JavaVMオブジェクトを保存しておきます。
Sound.cpp
/***********************************************
コマンドをJavaに送る
引数 _channel = チャンネル番号
_command = コマンド
_data = データ
_size = サイズ
_loop = ループ回数
_volume = 音量
***********************************************/
void SoundManager::set_command(int _channel, int _command, const void* _data, u32 _size, int _loop, float _volume)
{
JNIEnv* env;
Bool attach_flag = FALSE;
if ( g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6) < 0 ) {
if ( g_JavaVM->AttachCurrentThread(&env, NULL) < 0 ) {
return;
}
attach_flag = TRUE;
}
jclass clazz = env->FindClass("sys/SoundManager");
if ( clazz ) {
jmethodID mid = env->GetStaticMethodID(clazz, "set_command", "(SSIISF)V");
if ( mid ) {
env->CallStaticVoidMethod(clazz, mid, (short)_channel, (short)_command, (int)_data, (int)_size, (short)_loop, _volume);
}
}
if ( attach_flag ) {
g_JavaVM->DetachCurrentThread();
}
}
サウンド処理の命令を java側に送る関数です。
呼び出しに必要な JNIEnvを JavaVMオブジェクトから取得しています。
実行は、
865行:sys/SoundManagerクラスの
868行:静的関数 void set_command(short, short, int, int, short, float)を
871行:引数を指定して呼び出す
という流れになっています。
クラスや関数を文字列で指定したり、そこそこ重そうな処理なのでいろいろ使いまわししたいところですが、JNIEnv自体を毎回取得し直さなければいけないそうです。
セコメントをする