簡體   English   中英

在Mono Droid中創建數組並將其作為參數傳遞給JNI

[英]Creating and passing arrays as parameters to JNI in Mono Droid

在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

謝謝!

為什么將返回值包裝在JValue結構中?

我相信,只需從方法ToJavaObject返回IJavaObject即可。

那是:

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);
}

我從一位Xamarin開發人員那里獲得了以下工作解決方案。 實際上,它對理解JNI的工作原理大有幫助:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM