locked
Fail to create an activatable class(from WinRT) instance in JS Metro App

    Question

  • Hi friends, I've met with some strange failure creating an activatable class(from WinRT) instance in JS Metro App.
    Dont know if this is a potential bug in VS2011 Beta... I need you help to confirm or resolve this issue.

    Scenario 1. Create an activatable class(in WinRT) with a method that has base-class pointer as param,
    in Metro JS, if we call that method and pass instance of derived class to it, exception emerges.

    Reason may be that base class should not be sealed, it could not be activatable in Metro, so the method that uses
    base class type is in fact incomplete in JS view.

    (But it is a common usage in C++ to make use of polymorphism).

    Scenario 2. Use of overrided method:
    If we defined overrided method in an activatable class(in WinRT),
    trying to create an instance of that class in Metro JS will end in exception.

    Thanks!

    Thursday, March 08, 2012 4:41 PM

Answers

  • Maybe using an interface instead of a base class would address this issue.
    http://msdn.microsoft.com/en-us/library/windows/apps/hh755792(v=vs.110).aspx

    If you define IRegion as an interface, and Circle and Polygon as sealed ref classes which implement that interface, I believe you can define f(IRegion^) and have your scenario work.

    I have not verified this myself in Visual C++/CX, but I have implemented similar patterns in WinRT components authored in WRL.

    • Marked as answer by wqter Tuesday, March 13, 2012 6:23 AM
    Friday, March 09, 2012 1:25 AM
  • W,

    You would need to keep everything an interface.  You don't override functions in interfaces but simply your code behind the interface would be different.  You would not deal with classes at all in the Javascript.  Follow?

    -Jeff


    Jeff Sanders (MSFT)

    • Marked as answer by wqter Tuesday, March 13, 2012 6:23 AM
    Friday, March 09, 2012 12:07 PM
    Moderator

All replies

  • Hi W,

    All WinRT classes must be sealed if you intent to use them across the boundaries.  This is by design.

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, March 08, 2012 4:43 PM
    Moderator
  • That means I cannot define a method that uses base class pointer and pass subclass ptr at runtime?
    f(Region^ r);
    --------------------
    Circle c;// Circle is subclass of Region
    f(c); // Exception!

    Then I've got to create 1 method for each region type:
    f_Circle(Circle^ c);
    f_Polygon(Polygon^ p);
    ...

    Friday, March 09, 2012 12:50 AM
  • Maybe using an interface instead of a base class would address this issue.
    http://msdn.microsoft.com/en-us/library/windows/apps/hh755792(v=vs.110).aspx

    If you define IRegion as an interface, and Circle and Polygon as sealed ref classes which implement that interface, I believe you can define f(IRegion^) and have your scenario work.

    I have not verified this myself in Visual C++/CX, but I have implemented similar patterns in WinRT components authored in WRL.

    • Marked as answer by wqter Tuesday, March 13, 2012 6:23 AM
    Friday, March 09, 2012 1:25 AM
  • Great thx Murdoch! Your approach works! I could use interface pointer as param and pass implmentation class instance in. :D
    But as for overrided method, no luck again. If I wonna share some common attributes, I've got to use class, when I try to override
    the virtual functions defined in base class, exception happens again, :(

    Friday, March 09, 2012 2:40 AM
  • W,

    You would need to keep everything an interface.  You don't override functions in interfaces but simply your code behind the interface would be different.  You would not deal with classes at all in the Javascript.  Follow?

    -Jeff


    Jeff Sanders (MSFT)

    • Marked as answer by wqter Tuesday, March 13, 2012 6:23 AM
    Friday, March 09, 2012 12:07 PM
    Moderator
  • Thx Sanders

    In case I want to share some common attributes, I could use:
    class MyRegionClass : public RegionMeta/* class to hold shared attributes */, public IRegion /* interface class to define methods */
    {
    ...
    // implement the interface methods here
    };

    Tuesday, March 13, 2012 6:22 AM