質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JNI

JNI(Java Native Interface)は、Javaプラットフォームにおいて、Javaで記述されたプログラムと、他の言語で書かれたネイティブコードを連携するためのインタフェース仕様である

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

COCOS2D-X

COCOS2D-Xは、 2Dゲームを手軽に開発できるフレームワークのことです。 iPhone(iOS)向け、Android等に対応しており、 実質ワンソースで開発が可能です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1769閲覧

cocos2dxのandroid連携(jni)でカスタムクラスが入った配列を渡したいです。

kaji

総合スコア648

JNI

JNI(Java Native Interface)は、Javaプラットフォームにおいて、Javaで記述されたプログラムと、他の言語で書かれたネイティブコードを連携するためのインタフェース仕様である

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

COCOS2D-X

COCOS2D-Xは、 2Dゲームを手軽に開発できるフレームワークのことです。 iPhone(iOS)向け、Android等に対応しており、 実質ワンソースで開発が可能です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/04/06 03:35

編集2017/04/06 05:19

cocos2dxのandroid連携(jni)でカスタムクラスが入った配列を渡したいです。

渡したいデータ

本当は複数行にしたいけど、エラーが出るので、

java

1array = { 2 SampleInit{name->'a', level->1234}, 3 SampleInit{name->'b', level->2345}, 4 SampleInit{name->'c', level->3456} 5 };

とりあえず一行で今ためしてます。

java

1array = { 2 SampleInit{name->'a', level->1234} 3 };

SampleInitの中身はこんな感じです

java

1public class SampleInit { 2 public String name = ""; 3 public int level = 0; 4}

以下文字列配列を参考にして
https://teratail.com/questions/33572
以下の通りjniのコードを書いたのですが、

cpp

1 JNIEXPORT void JNICALL Java_jp_co_sample_SampleActivityBridge_onSampleInitLoaded(JNIEnv *env, jclass clazz, jobjectArray jsampleInits) 2 { 3 std::vector<CCSample*> sampleInit; 4 CCSampleRequestDelegate* listener = CCSampleRequest::getDelegate(); 5 if (listener != NULL) { 6 int length1 = env->GetArrayLength(jsampleInits); // ここが1であることは確認済み 7 jobjectArray jsampleInit = (jobjectArray)env->GetObjectArrayElement(jsampleInits, 0); 8 int length2 = env->GetArrayLength(jsampleInit); // ここでエラーになる(cocosビルドは通るけど、android-studioでbuildするとエラーになる) 9 /* ここいこうはまだ試してない 10 char *localArray; 11 localArray = (char *)malloc(sizeof(char)*3*3); 12 int i=0; 13 int j=0; 14 for(i=0; i<length1; i++){ 15 //jobjectArray oneDim= (jobjectArray)(*env)->GetObjectArrayElement(env, jsampleInit, i); 16 //jchar *element = (*env)->GetCharArrayElements(env, oneDim, 0); 17 for(j=0; j<length2; j++){ 18 //localArray[i*length2+j] = element[j]; 19 //printf("%c",localArray[i*length2+j]); 20 } 21 } 22 */

エラーはこのようになってます。

JNI WARNING: GetArrayLength: jarray arg has wrong type (expected array, got Ljp/co/sample/SampleInit;) 04-06 12:30:42.298 30285-30285/jp.co.sample.ccsample W/dalvikvm: in Ljp/co/sample/SampleActivityBridge;.onSampleLoaded:([Ljp/co/sample/SampleInit;)V (GetArrayLength) 04-06 12:30:42.298 30285-30285/jp.co.sample.ccsample I/dalvikvm: "main" prio=5 tid=1 RUNNABLE

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

int length1 = env->GetArrayLength(jsampleInits); //(1)
jobjectArray jsampleInit = (jobjectArray)env->GetObjectArrayElement(jsampleInits, 0); //(2)
int length2 = env->GetArrayLength(jsampleInit); //(3)

(2)の行がまずいようです。

自分もJNIに詳しくないので一つ一つ書いていきます。Java側のメソッド定義は次のようになっているということでよいでしょうか。

java

1package jp.co.sample; 2 3class SampleActivityBridge { 4 ... 5 static native void onSampleInitLoaded(SampleInit[] sampleInits); 6}

メソッドの引数はSampleInitの配列ですので、jsampleInitsにその配列のハンドルが渡されます。
(1)の行では配列の要素数を取り出していて結果が1とのことなので期待通り1要素の配列が渡されていると思います。

しかし(2)の行はこの配列の先頭要素を取り出しているので結果の型はJava側でいうとSampleInitです。これは配列ではありませんから以下のようにjobjectArrayにキャストすると破たんします。

jobjectArray jsampleInit = (jobjectArray)...

この行は次のようにすべきだと思います。

jobject jsampleInit = env->GetObjectArrayElement(jsampleInits, 0);

その後、jsampleInitに格納されているSampleInit型のインスタンスに対してnameフィールドなどをアクセスする流れになると思います。

投稿2017/04/07 04:20

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaji

2017/04/07 06:50

class SampleActivityBridge { ... static native void onSampleInitLoaded(SampleInit[] sampleInits); } このようになってます。 jobject jsampleInit = env->GetObjectArrayElement(jsampleInits, 0); を実行させましたが、 https://teratail.com/questions/71591 側の2017 4/7 15:28の解答のとおりとなってます。 https://teratail.com/questions/71591 へ解答を集約させます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問