0

mono Droid プロジェクトには、次のクラスの定義を含む .java ファイルがあります。

class A
{
    String str;
    String[] arr;

    public A(string str, string[] arr) 
    {
        this.str = str;
        this.arr = arr;
    }
}

foo(A[])JNI 環境を使用して C# から呼び出す必要があるメソッド。

C# ファイルには、対応する C# クラスのミラーリング定義があります。

class B
{
    string str;
    string[] arr;
    ...
}

C# コードの一部で配列を準備B[]し、メソッドに渡される新しい配列にすべてのオブジェクトをコピーしたいと考えています。そのために、B.ConvertArrayToJValueを返すメソッドを書きましたJValue

public class B
{
    string str;
    string[] arr;

    public B(string str, string[] arr) 
    {
        this.str = str;
        this.arr = arr;
    }

    public JValue ToJavaObject()
    {
        IntPtr classA = JNIEnv.FindClass("com/packagename/A");
        IntPtr method_ctor = JNIEnv.GetMethodID(classA, "<init>", "(Ljava/lang/String;[Ljava/lang/String;)V");
        Java.Lang.String.[] tempValues = new Java.Lang.String[this.arr.Length];
        for (int i = 0; i < this.arr.Length; ++i)
        {
            tempValues[i] = new Java.Lang.String(this.arr[i]);
        }

        JValue strArray = new JValue(Java.Lang.Object.FromArray<Java.Lang.String>(tempValues));
        IntPtr result = JNIEnv.NewObject(classA, method_ctor, new JValue[]{new JValue(new Java.Lang.String(this.str)), strArray});
        return new JValue(new Java.Lang.Object(result, JniHandleOwnership.DoNotTransfer));
    }

    public static JValue ConvertArrayToJValue(B[] arr)
    {
        JValue[] tempCopy = new JValue[arr.Length];
        for (int i = 0; i < arr.Length; ++i)
        {
            tempCopy[i] = arr[i].ToJavaObject();
        }
        //FIXME: doesn't properly convert arrays! 
        // Compiles but throws an exception in runtime: "Can't convert JValue to IJavaObject"
        return new JValue(Java.Lang.Object.FromArray<JValue>(tempCopy));
    }

}

C# コードの別の場所:

b[] = new B[]{ ... };

IntPtr method_foo = JNIEnv.GetStaticMethodID(classC, "foo", "([Lcom/packagename/A;)V");
JNIEnv.CallStaticVoidMethod(classC, method_foo, new JValue[] { B.ConvertArrayToJValue(b) });

これはうまくいきません。文字列の配列は適切に生成されているように見えます (少なくとも C# 文字列は Java Strings (?) に変換されているようです) が、型のカスタム オブジェクトの配列を作成しようとするとBエラーが発生します:

Can't convert JValue to IJavaObject

ありがとう!

4

2 に答える 2

0

JValue戻り値を構造体でラップするのはなぜですか?

IJavaObjectメソッドから戻るだけToJavaObjectでうまくいくと思います。

あれは:

public IJavaObject ToJavaObject()
{
    // Snip
    return new Java.Lang.Object(result, JniHandleOwnership.DoNotTransfer);
}

public static IJavaObject ConvertArrayToJavaObject(B[] arr)
{
    // Snip
    return Java.Lang.Object.FromArray<IJavaObject>(tempCopy);
}
于 2013-03-05T23:32:07.767 に答える
0

Xamarin 開発者の 1 人から次の実用的なソリューションを入手しました。実際、JNI の仕組みを理解するのに大いに役立ちます。

http://forums.xamarin.com/discussion/1930/creating-arrays-of-custom-java-objects-in-jni

于 2013-03-10T13:29:39.987 に答える