Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm newbie in Xamarin with Visual Studio. There is an existing xamarin android project in which I had to add a Jar files (SDK), so I created a Binding Library, however it's throwing some errors that I'm trying to solve them by using Metadata.xml, one of them is as follows:

'DeviceService' does not implement interface member 'IDeviceService.SetSignResult(int)'

Searching into api.xml I've found this:

<class abstract="false" deprecated="not deprecated" extends="android.app.Service" extends-generic-aware="android.app.Service" final="false" name="DeviceService" static="false" visibility="public">
<implements name="com.company.deviceService.IDeviceService" name-generic-aware="com.company.deviceService.IDeviceService">
</implements>
<constructor deprecated="not deprecated" final="false" name="DeviceService" static="false" type="com.company.deviceService.DeviceService" visibility="public">
</constructor>
...
<method abstract="false" deprecated="not deprecated" final="false" name="setSignResult" native="false" return="void" static="false" synchronized="false" visibility="public">
<parameter name="p0" type="int">
</parameter>
</method>

<method abstract="false" deprecated="not deprecated" final="false"   name="getSignResult" native="false" return="int" static="false" synchronized="false" visibility="public">
</method>
...
</class>

In the Interface there is such method:

IntPtr id_setSignResult_I;
        public unsafe void SetSignResult (int p0)
        {
            if (id_setSignResult_I == IntPtr.Zero)
                id_setSignResult_I = JNIEnv.GetMethodID (class_ref, "setSignResult", "(I)V");
            JValue* __args = stackalloc JValue [1];
            __args [0] = new JValue (p0);
            JNIEnv.CallVoidMethod (Handle, id_setSignResult_I, __args);
        }

However when I search into generated class DeviceService.cs I found this:

static Delegate cb_setSignResult_I;
#pragma warning disable 0169
        static Delegate GetSetSignResult_IHandler ()
        {
            if (cb_setSignResult_I == null)
                cb_setSignResult_I = JNINativeWrapper.CreateDelegate ((Action<IntPtr, IntPtr, int>) n_SetSignResult_I);
            return cb_setSignResult_I;
        }

        static void n_SetSignResult_I (IntPtr jnienv, IntPtr native__this, int p0)
        {
            global::com.company.deviceService.DeviceService __this = global::Java.Lang.Object.GetObject<global::com.company.deviceService.DeviceService> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
            __this.SignResult = p0;
        }
#pragma warning restore 0169

        static IntPtr id_getSignResult;
        static IntPtr id_setSignResult_I;

        public virtual unsafe int SignResult {
            // Metadata.xml XPath method reference: path="/api/package[@name='com.company.deviceService']/class[@name='DeviceService']/method[@name='getSignResult' and count(parameter)=0]"
            [Register ("getSignResult", "()I", "GetGetSignResultHandler")]
            get {
                if (id_getSignResult == IntPtr.Zero)
                    id_getSignResult = JNIEnv.GetMethodID (class_ref, "getSignResult", "()I");
                try {

                    if (GetType () == ThresholdType)
                        return JNIEnv.CallIntMethod  (Handle, id_getSignResult);
                    else
                        return JNIEnv.CallNonvirtualIntMethod  (Handle, ThresholdClass, JNIEnv.GetMethodID (ThresholdClass, "getSignResult", "()I"));
                } finally {
                }
            }
            // Metadata.xml XPath method reference: path="/api/package[@name='com.company.deviceService']/class[@name='DeviceService']/method[@name='setSignResult' and count(parameter)=1 and parameter[1][@type='int']]"
            [Register ("setSignResult", "(I)V", "GetSetSignResult_IHandler")]
            set {
                if (id_setSignResult_I == IntPtr.Zero)
                    id_setSignResult_I = JNIEnv.GetMethodID (class_ref, "setSignResult", "(I)V");
                try {
                    JValue* __args = stackalloc JValue [1];
                    __args [0] = new JValue (value);

                    if (GetType () == ThresholdType)
                        JNIEnv.CallVoidMethod  (Handle, id_setSignResult_I, __args);
                    else
                        JNIEnv.CallNonvirtualVoidMethod  (Handle, ThresholdClass, JNIEnv.GetMethodID (ThresholdClass, "setSignResult", "(I)V"), __args);
                } finally {
                }
            }
        }

For some reason Binding Generator incorrectly infer method implementation or return type, I don't know, and looking into api.xml it seems to be in correct way: void setSignResult (int p0). I tried to modify behaviour by using metadata.xml with same error:

  <attr path="/api/package[@name='Com.Company.deviceservice']/class[@name='DeviceService']/method[@name='SetSignResult' 
    and count(parameter)=1
    and parameter[1][@type='int']]/parameter[1]"
    name="managedReturn">Java.Lang.Void</attr>

I looked for another Interface method implementation, similar to before mentioned to compare with it, and I found it correctly generates the method, take at look:

static IntPtr id_bcrSymbologyToText_I;
        [Register ("bcrSymbologyToText", "(I)Ljava/lang/String;", "GetBcrSymbologyToText_IHandler")]

        public virtual unsafe string BcrSymbologyToText (int p0)
        {
            if (id_bcrSymbologyToText_I == IntPtr.Zero)
                id_bcrSymbologyToText_I = JNIEnv.GetMethodID (class_ref, "bcrSymbologyToText", "(I)Ljava/lang/String;");
            try {
                JValue* __args = stackalloc JValue [1];
                __args [0] = new JValue (p0);

                if (GetType () == ThresholdType)
                    return JNIEnv.GetString (JNIEnv.CallObjectMethod  (Handle, id_bcrSymbologyToText_I, __args), JniHandleOwnership.TransferLocalRef);
                else
                    return JNIEnv.GetString (JNIEnv.CallNonvirtualObjectMethod  (Handle, ThresholdClass, JNIEnv.GetMethodID (ThresholdClass, "bcrSymbologyToText", "(I)Ljava/lang/String;"), __args), JniHandleOwnership.TransferLocalRef);
            } finally {
            }
        }

Please need your help soon!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
180 views
Welcome To Ask or Share your Answers For Others

1 Answer

Found answer:

Xamarin Binding Generator (Who Works on a Binding Library), are translating in wrong way from java classes to c# classes some java code that it can't perform reingenieering, so generator is creating a setSignResult as a property result from a java method. The way to fix those things is using metadata.xml for some type of errors or else, implementing, in my case, the missing method by creating a partial class with same autogenerated class name. Since Binding Generator created DeviceService partial class with its own implementation, I created another DeviceService partial class implementing missing method with following implementation:

public partial class DeviceService
    {
        public void SetSignResult(int p)
        {
            SignResult = p;
        }
}

Works perfect!

thanks to all


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...