microsoft / Chakra-Samples

Repository for Chakra JavaScript engine related samples.
MIT License
216 stars 84 forks source link

Passing object to runtime component #19

Closed SrinivasGourarum closed 8 years ago

SrinivasGourarum commented 8 years ago
  1. While trying to pass an object to the projected runtime component, I am getting an error saying "type mismatch. The sample is uploaded @ https://onedrive.live.com/redir?resid=9C4512A9CBBBEB98!114&authkey=!AMRXOrhTk2Ojq6Q&ithint=file%2czip . How do I pass the object which can be accepted in the runtime component as a dictionary?
  2. Even when returning a dictionary from the runtime Component ("getMap2"), it is returning as "System.Collections.Generic.Dictionary`2[System.String,System.Int32]" and not as [object Object].

Is this expected behavior? Please click on the "Execute" button to execute the script in the file "script11.js".

liminzhu commented 8 years ago

@robpaveza

robpaveza commented 8 years ago

Hi @SrinivasGourarum -

There are a couple of things in play.

In Windows Runtime parlance, a C# IDictionary<TKey, TValue> maps to the ABI type IMap<K, V>. Because of object identity, when you retrieve a new IDictionary<TKey, TValue>, that is projected as an IMap<K, V> to JavaScript, with corresponding clear(), getView(), hasKey(key), etc. methods. That's why, for your question #2, when getMap2() returns a System.Collections.Generic.Dictionary'2[System.String, System.Int32] - that's the underlying type being represented (the .NET type is providing the backing implementation for IMap<K, V>).

For #1, a JavaScript object cannot implement an arbitrary Windows Runtime interface, and there isn't a stock implementation of IMap<K, V>. This is a limitation of the type system interoperability between JavaScript and Windows Runtime. You must source an implementation from somewhere else. One example of this might be from getMap2; for example, if you change your code:

var myClass = new RuntimeComponent.SampleClass();
var retVal1 = myClass.getMap2();
Debug.writeln(retVal1);
retVal1.insert('key5', 5881);  // changed
var retVal = myClass.getMap1(retVal1);  // changed
Debug.writeln(retVal);

The primary difference here is that C# has produced a Windows Runtime IMap<string, int> and returned it from myClass.getMap2(). You mutate it, and then pass it back to myClass.getMap1(). The underlying Windows Runtime IMap<string, int> is passed and object identity is preserved.

I hope this helps answer your question.