NDKでlibdvmを使用してJNI_GetCreatedJavaVMsを利用したいのですが

1,901 views
Skip to first unread message

山田

unread,
Oct 13, 2011, 7:04:39 AM10/13/11
to Android-SDK-Japan
現在NDKを使用して開発を行っており
C++側からJavaの関数を呼び出そうと考え
現在NDKを利用して開発を行っており
c++側の関数から
JavaVM を取得し
JNIEnvを利用して
javaの関数を呼び出そうかと考えているのですが

jint ret = JNI_GetCreatedJavaVMs(&vm, 1, &ct);
を呼び出したときに

test.cpp:(.text._Z5getVMv+0xa): undefined reference to
`JNI_GetCreatedJavaVM
s'
collect2: ld returned 1 exit status

というエラーが出て悩んでいるのですが
libdvmがないのかなと思い
Android.mkに
LOCAL_SHARED_LIBRARIES := libdvm
と追加したのですが
まだエラーが出てしまいます。

Application.mkとかにもなにか必要なのかと悩んでいるのですが
なにか方法がありましたら
ご教授いただけないでしょうか、宜しくお願いいたします。

Tatsuya Matsumoto

unread,
Oct 13, 2011, 7:15:27 AM10/13/11
to android-...@googlegroups.com
松本と申します。

JNI_GetCreatedJavaVM関数の代わりに、GetJavaVM関数を呼び出すのはどうでしょうか。
もしくは、JNI_OnLoadで渡されるJavaVM*型の変数をグローバルに保存しておくなど・・・。


_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/ 松本達弥 法政大学 情報科学部
_/ MAIL: tma...@gmail.com
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

2011/10/13 山田 <jou...@crest.ocn.ne.jp>:

> --
> このメールは Google グループのグループ「Android-SDK-Japan」の登録者に送られています。
> このグループに投稿するには、android-...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-sdk-ja...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-sdk-japan?hl=ja からこのグループにアクセスしてください。
>
>

山田

unread,
Oct 13, 2011, 8:47:50 AM10/13/11
to Android-SDK-Japan
松本さまありがとうございます

なるほどJNI_OnLoadでも取得できるのかと思い
以下のようにしてみたのですが

EXPORT jint JNI_OnLoad( JavaVM* vm, void* reserved )
{
JNIEnv* env = NULL;
jint result = -1;

if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK ){
return result;
}

return JNI_VERSION_1_6;
}

(*vm)->GetEnvの所で

error: base operand of '->' has non-pointer type '_JavaVM'

といったようなエラーが出てしまうのですが
なにか方法に間違いがありましたら
教えていただけないでしょうか
何度も申し訳ないのですが宜しくお願いします。

Tatsuya Matsumoto

unread,
Oct 13, 2011, 9:09:27 AM10/13/11
to android-...@googlegroups.com
松本です。

先ほどのメールによると、C++環境で開発を行なっているということでしたが、
この書き方はC用のJNI関数の呼び出し方ですのでエラーになってしまいます。

>> (*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6)

vm->GetEnv((void**) &env, JNI_VERSION_1_6)
に書き換えれば、恐らくコンパイルできるかと思います。

2011/10/13 山田 <jou...@crest.ocn.ne.jp>:

山田

unread,
Oct 13, 2011, 11:10:25 PM10/13/11
to Android-SDK-Japan
ご返信ありがとうございます。
vm->GetEnv((void**) &env, JNI_VERSION_1_6)
で無事にコンパイルが通りました。
そこからjavaの関数を呼び出すことには成功したのですが
javaの関数を呼び出した直後に

DEBUG/AndroidRuntime(29198): Shutting down VM
WARN/dalvikvm(29198): threadid=1: thread exiting with uncaught
exception (group=0x40015578)
ERROR/AndroidRuntime(29198): FATAL EXCEPTION: main
ERROR/AndroidRuntime(29198): java.lang.RuntimeException: Can't create
handler inside thread that has not called Looper.prepare()
INFO/ActivityManager(132): Start proc com.wssyncmldm for service
com.wssyncmldm/.DMService: pid=29237 uid=1000 gids={3003, 1015, 2001,
3002, 3001, 1001, 1006}

とアプリが強制終了してしまいます。

c++側の処理では
public voi cTest(){
jclass cls = g_env->FindClass("test/Test");
methodID cns = g_env->GetMethodID(cls, "<init>", "()V");
jobject obj = g_env->NewObject(cls, cns);
jmethodID vTestID = g_env->GetMethodID(cls, "jTest", "()V");
g_env->CallVoidMethod(obj, vTestID);
}
java側の処理では
public void jTest()
{
Log.d("testpas", "Fishing : Test c++ -> java !!!");
}

としているだけなのですが
javaで文字を表示してc++側に戻って来て関数を抜けた直後に
強制終了してしまいます。

原因など思い当たるところがあれば
ご教授いただけないでしょうか、宜しくお願いいたします。

山田

unread,
Oct 14, 2011, 12:21:58 AM10/14/11
to Android-SDK-Japan
申し訳ありません、先ほどの質問なのですが
自己解決しました
まちがえて呼び出しているスレッドとは別の関数を呼び出していたのが原因でした。
松本様、ご教授いただき真にありがとうございました。
Reply all
Reply to author
Forward
0 new messages