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
ありがとう!