Embedded API: calling explicit interface properties

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Embedded API: calling explicit interface properties

Jonathan Mitchell
Hi

I have a class that implements the following two interfaces and I am having trouble accessing explicit interface properties via the embedded API.
My unit tests fail (see below).

The explicit interface properties are found okay but the property assignment fails in a way which makes me think there is a parameter type problem.
Is there anything I should be aware of with regard to constructing the property access signature?
If I log the mono class method info it looks okay - again this is listed below.

Any suggestions would be appreciated.

MONO
======

    public interface IReferenceObject1 : IReferenceObjectBase
    {
        int ExIntTestProperty { get; set; }
    }
    public interface IReferenceObject2 : IReferenceObjectBase
    {
        float ExIntTestProperty { get; set; }
    }

    public class ReferenceObject : IReferenceObject1, IReferenceObject2
        {
        // explicit interface properties
        /*
         * Here we have one property with 3 different return types
         * two of which should be accessible via explicit interface references
         */
        public bool ExIntTestProperty { get; set; }
        float IReferenceObject2.ExIntTestProperty { get; set; }
        int IReferenceObject1.ExIntTestProperty { get; set; }

        // get interfaces
        public IReferenceObject1 ReferenceObject1 {
            get {
                return (IReferenceObject1)this;
            }
        }

        public IReferenceObject2 ReferenceObject2 {
            get {
                return (IReferenceObject2)this;
            }
        }
}

// MonoClass dump
// iterate over mono_class_get_methods

============== Mono Class Info ========================

2014-07-15 11:54:14.544 otest[4933:303] Class namespace : Dubrovnik.UnitTests
2014-07-15 11:54:14.545 otest[4933:303] Class name : IReferenceObject1
2014-07-15 11:54:14.545 otest[4933:303] Class type name : Dubrovnik.UnitTests.IReferenceObject1
2014-07-15 11:54:14.545 otest[4933:303] Method count : 2
2014-07-15 11:54:14.545 otest[4933:303] Method name: Dubrovnik.UnitTests.IReferenceObject1:get_ExIntTestProperty ()
2014-07-15 11:54:14.546 otest[4933:303] Method name: Dubrovnik.UnitTests.IReferenceObject1:set_ExIntTestProperty (int)
2014-07-15 11:54:14.546 otest[4933:303] Interface name: IReferenceObjectBase
2014-07-15 11:54:23.206 otest[4933:303]

============== Mono Class Info ========================

2014-07-15 11:54:23.207 otest[4933:303] Class namespace : Dubrovnik.UnitTests
2014-07-15 11:54:23.207 otest[4933:303] Class name : IReferenceObject2
2014-07-15 11:54:23.208 otest[4933:303] Class type name : Dubrovnik.UnitTests.IReferenceObject2
2014-07-15 11:54:23.208 otest[4933:303] Method count : 2
2014-07-15 11:54:23.208 otest[4933:303] Method name: Dubrovnik.UnitTests.IReferenceObject2:get_ExIntTestProperty ()
2014-07-15 11:54:23.209 otest[4933:303] Method name: Dubrovnik.UnitTests.IReferenceObject2:set_ExIntTestProperty (single)
2014-07-15 11:54:23.210 otest[4933:303] Interface name: IReferenceObjectBase

Obj-C property accessors
=====================

// IReferenceObject1 returns Int

        // Managed property name : ExIntTestProperty
        // Managed property type : System.Int32
    @synthesize exIntTestProperty = _exIntTestProperty;
    - (int32_t)exIntTestProperty
    {
                MonoObject *monoObject = [self getMonoProperty:"ExIntTestProperty"];
                _exIntTestProperty = DB_UNBOX_INT32(monoObject);

                return _exIntTestProperty;
        }
    - (void)setExIntTestProperty:(int32_t)value
        {
                _exIntTestProperty = value;
                MonoObject *monoObject = DB_VALUE(value);
                [self setMonoProperty:"ExIntTestProperty" valueObject:monoObject];
        }

// IReferenceObject2 returns float

        // Managed property name : ExIntTestProperty
        // Managed property type : System.Single
    @synthesize exIntTestProperty = _exIntTestProperty;
    - (float)exIntTestProperty
    {
                MonoObject *monoObject = [self getMonoProperty:"ExIntTestProperty"];
                _exIntTestProperty = DB_UNBOX_FLOAT(monoObject);

                return _exIntTestProperty;
        }
    - (void)setExIntTestProperty:(float)value
        {
                _exIntTestProperty = value;
                MonoObject *monoObject = DB_VALUE(value);
                [self setMonoProperty:"ExIntTestProperty" valueObject:monoObject];          
        }

Obj-C unit test
============

    // query explicit interface implementation properties.
    // we should be able to access the same property with three different return types via the
    // original object and two explicit interface references.
   
    // BOOL
    BOOL boolValue = [(DBUReferenceObject *)refObject exIntTestProperty];   // cast need to silence type warning
    NSAssert(boolValue == YES, DBUEqualityTestFailed);
   
    // int
    Dubrovnik_UnitTests_IReferenceObject1 *refObject1 = [refObject referenceObject1];
    [refObject1 logMonoClassInfo];
    [refObject1 setExIntTestProperty:89467];
    int32_t intValue = [refObject1 exIntTestProperty];
   
#warning failing test code - return value is 123
    NSAssert(intValue == 89467, DBUEqualityTestFailed);
   
    // float
    Dubrovnik_UnitTests_IReferenceObject2 *refObject2 = [refObject referenceObject2];
    [refObject2 logMonoClassInfo];
    [refObject2 setExIntTestProperty:20202.f];
    float floatValue = [refObject2 exIntTestProperty];
   
#warning failing test code - return value is 0
    NSAssert(floatValue == 20202.f, DBUEqualityTestFailed);

Thanks

Jonathan












_______________________________________________
Mono-list maillist  -  [hidden email]
http://lists.ximian.com/mailman/listinfo/mono-list
Reply | Threaded
Open this post in threaded view
|

Re: Embedded API: calling explicit interface properties

Robert Jordan
On 15.07.2014 13:24, Jonathan Mitchell wrote:
> Hi
>
> I have a class that implements the following two interfaces and I am having trouble accessing explicit interface properties via the embedded API.
> My unit tests fail (see below).
>
> The explicit interface properties are found okay but the property assignment fails in a way which makes me think there is a parameter type problem.
> Is there anything I should be aware of with regard to constructing the property access signature?
> If I log the mono class method info it looks okay - again this is listed below.

IIRC, the name of properties (and methods) of explicit interfaces
must be prefixed with the interface name, e.g.:

[self getMonoProperty:"IReferenceObject2_ExIntTestProperty"]

I'm not sure about the delimiter, but I believe it's "_".

Robert


_______________________________________________
Mono-list maillist  -  [hidden email]
http://lists.ximian.com/mailman/listinfo/mono-list
Reply | Threaded
Open this post in threaded view
|

Re: Embedded API: calling explicit interface properties

Jonathan Mitchell



On 15 Jul 2014, at 14:50, Robert Jordan <[hidden email]> wrote:

> On 15.07.2014 13:24, Jonathan Mitchell wrote:
>> Hi
>>
>> I have a class that implements the following two interfaces and I am having trouble accessing explicit interface properties via the embedded API.
>
> IIRC, the name of properties (and methods) of explicit interfaces
> must be prefixed with the interface name, e.g.:
>
> [self getMonoProperty:"IReferenceObject2_ExIntTestProperty"]
>
> I'm not sure about the delimiter, but I believe it's "_".
Thanks for the tip.

Looking at the ReferenceObject I can see that there is a namespace + interface name prefix before the getter and setter functions.

2014-07-15 15:55:10.904 otest[16383:303] Method name: Dubrovnik.UnitTests.ReferenceObject:get_ExIntTestProperty ()
2014-07-15 15:55:10.904 otest[16383:303] Method name: Dubrovnik.UnitTests.ReferenceObject:set_ExIntTestProperty (bool)
2014-07-15 15:55:10.904 otest[16383:303] Method name: Dubrovnik.UnitTests.ReferenceObject:Dubrovnik.UnitTests.IReferenceObject2.get_ExIntTestProperty ()
2014-07-15 15:55:10.905 otest[16383:303] Method name: Dubrovnik.UnitTests.ReferenceObject:Dubrovnik.UnitTests.IReferenceObject2.set_ExIntTestProperty (single)
2014-07-15 15:55:10.905 otest[16383:303] Method name: Dubrovnik.UnitTests.ReferenceObject:Dubrovnik.UnitTests.IReferenceObject1.get_ExIntTestProperty ()
2014-07-15 15:55:10.905 otest[16383:303] Method name: Dubrovnik.UnitTests.ReferenceObject:Dubrovnik.UnitTests.IReferenceObject1.set_ExIntTestProperty (int)

When using the IReferenceObject1 I see the accessors without the prefix and reporting the correct argument type.
To me it looks like we are good to go - but the the unit test still fails.
Perhaps I am sort of expecting the C API to behave like its managed counterpart in this case and allow me to access the explicit property through the interface.
I also build my property get method names up explicitly from the property name rather than using mono_class_get_property_from_name.
I will have to dig into this a bit more.

2014-07-15 16:01:44.555 otest[16444:303] Method count : 2
2014-07-15 16:01:44.555 otest[16444:303] Method name: Dubrovnik.UnitTests.IReferenceObject1:get_ExIntTestProperty ()
2014-07-15 16:01:44.556 otest[16444:303] Method name: Dubrovnik.UnitTests.IReferenceObject1:set_ExIntTestProperty (int)

IReferenceObject2

2014-07-15 16:01:44.557 otest[16444:303] Method name: Dubrovnik.UnitTests.IReferenceObject2:get_ExIntTestProperty ()
2014-07-15 16:01:44.558 otest[16444:303] Method name: Dubrovnik.UnitTests.IReferenceObject2:set_ExIntTestProperty (single)

Jonathan
_______________________________________________
Mono-list maillist  -  [hidden email]
http://lists.ximian.com/mailman/listinfo/mono-list
Reply | Threaded
Open this post in threaded view
|

Re: Embedded API: calling explicit interface properties

Jonathan Mitchell

On 15 Jul 2014, at 16:31, Jonathan Mitchell <[hidden email]> wrote:

> When using the IReferenceObject1 I see the accessors without the prefix and reporting the correct argument type.
> To me it looks like we are good to go - but the the unit test still fails.
> Perhaps I am sort of expecting the C API to behave like its managed counterpart in this case and allow me to access the explicit property through the interface.
That assumption was my downfall.
Even when targeting an explicit interface i need to prefix the property/method name with the a full interface identifier:

    - (int32_t)exIntTestProperty
    {
                MonoObject *monoObject = [self getMonoProperty:"Dubrovnik.UnitTests.IReferenceObject1.ExIntTestProperty"];
                _exIntTestProperty = DB_UNBOX_INT32(monoObject);

                return _exIntTestProperty;
        }

Thanks

Jonathan
_______________________________________________
Mono-list maillist  -  [hidden email]
http://lists.ximian.com/mailman/listinfo/mono-list