#include "DxLib.h"
#include <string.h>
// クリップボードにテキストを設定する
int ClipboardText_Set( const char *Text )
{
JNIEnv *env ;
const ANativeActivity *NativeActivity ;
// アプリの NativeActivity を取得
NativeActivity = GetNativeActivity() ;
// Java の関数 SetClipboardText の呼び出し
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return -1 ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// 関数の引数に渡す jstring を作成
jstring jstring_SetText = env->NewStringUTF( Text ) ;
// Java のクラス MainActivity のメンバー関数 SetClipboardText の ID を取得
jmethodID jmethodID_SetClipboardText = env->GetMethodID( jclass_MainActivity, "SetClipboardText", "(Ljava/lang/String;)V" ) ;
// Java のクラス MainActivity のメンバー関数 SetClipboardText の呼び出し
env->CallVoidMethod( NativeActivity->clazz, jmethodID_SetClipboardText, jstring_SetText ) ;
// 関数の引数用に作成した jstring の参照を削除
env->DeleteLocalRef( jstring_SetText ) ;
// Java のクラス MainActivity の参照を削除
env->DeleteLocalRef( jclass_MainActivity ) ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
}
// Java の関数 SetClipboardText の処理完了待ち
while( true )
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return -1 ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー関数 FinishClipboardProcess の ID を取得
jfieldID jfieldID_FinishClipboardProcess = env->GetFieldID( jclass_MainActivity, "FinishClipboardProcess", "I" ) ;
// Java のクラス (プロジェクト名) のメンバー変数 FinishClipboardProcess の値をローカル変数 FinishClipboardProcess に代入
int FinishClipboardProcess = env->GetIntField( NativeActivity->clazz, jfieldID_FinishClipboardProcess ) ;
// Java のクラス MainActivity の参照を削除
env->DeleteLocalRef( jclass_MainActivity ) ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
// 処理が完了していたらループを抜ける
if( FinishClipboardProcess == 1 )
{
break ;
}
}
// 正常終了
return 0 ;
}
// クリップボードのテキストを取得する
int ClipboardText_Get( char *TextBuffer, int TextBufferSize )
{
JNIEnv *env ;
const ANativeActivity *NativeActivity ;
// アプリの NativeActivity を取得
NativeActivity = GetNativeActivity() ;
// Java の関数 GetClipboardText の呼び出し
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return -1 ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー関数 GetClipboardText の ID を取得
jmethodID jmethodID_GetClipboardText = env->GetMethodID( jclass_MainActivity, "GetClipboardText", "()V" ) ;
// Java のクラス MainActivity のメンバー関数 GetClipboardText の呼び出し
env->CallVoidMethod( NativeActivity->clazz, jmethodID_GetClipboardText ) ;
// Java のクラス MainActivity の参照を削除
env->DeleteLocalRef( jclass_MainActivity ) ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
}
// Java の関数 GetClipboardText の処理完了待ち
while( true )
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return -1 ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー関数 FinishClipboardProcess の ID を取得
jfieldID jfieldID_FinishClipboardProcess = env->GetFieldID( jclass_MainActivity, "FinishClipboardProcess", "I" ) ;
// Java のクラス (プロジェクト名) のメンバー変数 FinishClipboardProcess の値をローカル変数 FinishClipboardProcess に代入
int FinishClipboardProcess = env->GetIntField( NativeActivity->clazz, jfieldID_FinishClipboardProcess ) ;
// 処理が完了していたらテキストを取得する
if( FinishClipboardProcess == 1 )
{
// Java のクラス MainActivity のメンバー変数 ClipboardText の ID を取得
jfieldID jfieldID_ClipboardText = env->GetFieldID( jclass_MainActivity, "ClipboardText", "Ljava/lang/String;" ) ;
// Java のクラス MainActivity のメンバー変数 ClipboardText の jstring オブジェクトを取得
jstring jstring_ClipboardText = ( jstring )env->GetObjectField( NativeActivity->clazz, jfieldID_ClipboardText ) ;
// Java のクラス MainActivity のメンバー変数 ClipboardText の jstring から C++ 用の文字列のアドレスを取得
const char *chars_ClipboardText = env->GetStringUTFChars( jstring_ClipboardText, NULL ) ;
// 文字列をローカル変数 ClipboardText にコピー
strncpy( TextBuffer, chars_ClipboardText, TextBufferSize - 1 ) ;
// Java のクラス MainActivity のメンバー変数 ClipboardText の jstring から取得した C++ 用の文字列のアドレスを解放
env->ReleaseStringUTFChars( jstring_ClipboardText, chars_ClipboardText ) ;
// Java のクラス MainActivity のメンバー変数 ClipboardText の jstring オブジェクトの参照を削除
env->DeleteLocalRef( jstring_ClipboardText ) ;
}
// Java のクラス MainActivity の参照を削除
env->DeleteLocalRef( jclass_MainActivity ) ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
// 処理が完了していたらループを抜ける
if( FinishClipboardProcess == 1 )
{
break ;
}
}
// 正常終了
return 0 ;
}
int android_main( void )
{
// 背景の色をグレーにする
SetBackgroundColor( 128,128,128 ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// クリップボードにテキストを設定する
ClipboardText_Set( "テストテキスト" ) ;
// メインループ
while( ProcessMessage() == 0 )
{
char StringBuffer[ 256 ] ;
// 画面のクリア
ClearDrawScreen() ;
// クリップボードのテキストを取得
ClipboardText_Get( StringBuffer, sizeof( StringBuffer ) ) ;
// クリップボードのテキストを画面に表示
DrawFormatString( 0, 0, GetColor( 255,255,255 ), "クリップボードのテキスト[ %s ]", StringBuffer ) ;
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
以上です。
これでプロジェクトを実行すると、画面に『クリップボードのテキスト[ テストテキスト ]』と表示されます。
詳細は割愛しますが、C++ から Java にアクセスする基本的な流れは。
① AttachCurrentThreadAsDaemon でソフト実行用スレッドと JavaVM を関連付け、JNIEnv も取得。
② GetObjectClass でアプリの Java クラスを取得。
③ GetMethodID や GetFieldID で Java の関数や変数の ID を取得。
④ Call???Method や Get???Field で Java の関数の呼び出しや変数の値を取得。
⑤ DeleteLocalRef で Get???Field で取得したオブジェクト系の変数の参照を削除。
⑥ DeleteLocalRef で GetObjectClass で取得したアプリの Java クラスの参照を削除。
⑦ DetachCurrentThread でソフト実行用スレッドと JavaVM の関連付けを終了。
となります。
C++ と Java でのやり取りを行う機能( JNI( Java Native Interface ) ) の詳しい扱い方については、検索サイトで
『Android Java JNI』などのキーワードで検索して調べてみてください。
ただ、今回のサンプルでは JNI を使用した処理は ClipboardText_Set と ClipboardText_Get に纏められているので、
そのまま使う場合は JNI のことを意識しなくてもクリップボードの機能を使用することができます。
戻る