サウンド処理は非同期で その22013/11/29

サウンドの非同期処理のための 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自体を毎回取得し直さなければいけないそうです。