Are you the publisher? Claim or contact us about this channel


Embed this content in your HTML

Search

Report adult content:

click to rate:

Account: (login)

More Channels


Showcase


Channel Catalog


Channel Description:

ClearScript is a library that makes it easy to add scripting to your .NET applications. It currently supports JavaScript (via V8 and JScript) and VBScript.

older | 1 | .... | 36 | 37 | (Page 38) | 39 | 40 | .... | 115 | newer

    0 0

    can't handle the case where person.Name returns nothing, and that's because nothing is a special object reference that requires a set statement rather than simple assignment. Is that your understanding as well?
    String value cannot be nothing, nothing keyword can be used for class objects only.
    ClearScript changes the .NET default marshaling of string value from null to nothing.
    Person name is ''
    Have you made any modifications to ClearScript that could have changed the behavior?
    Sorry, that my mistake, ignore.

    0 0

    OK, so:

    1. The problem occurs only when MarshalNullAsDispatch is in effect.
    2. Host members (fields, properties, methods) that return strings should overrideMarshalNullAsDispatch and marshal null return values as DBNull.
    If all of that is correct, what other return types should override MarshalNullAsDispatch? One thing that comes to mind is nullable numerics such as int?. Anything else?

    0 0

    If all of that is correct, what other return types should override MarshalNullAsDispatch? One thing that comes to mind is nullable numerics such as int?. Anything else?
    Only host members with strongly typed objects that derive from the Object class with specific reference type can return DispatchWrapper(null) in case of null.
    Host members like string, object, nullable<T> should return DBNull.
    I'm not sure about DBNull, because .NET marshal a null value as VT_EMPTY and not as VT_NULL like DBNull

    http://msdn.microsoft.com/en-us/library/2x07fbw8%28v=vs.110%29.aspx

    0 0

    Hi ifle,

    Only host members with strongly typed objects that derive from the Object class with specific reference type can return DispatchWrapper(null) in case of null.

    Well, not quite, because that description applies to .NET strings :)

    Host members like string, object, nullable<T> should return DBNull.

    That doesn't seem completely correct either. A value type T that isn't numeric or boolean turns into an object reference on the script side, so a Nullable<T> without a value should probably be marshalled as nothing. And object is completely ambiguous; ideal null marshaling in that case depends entirely on what the script expects.

    I'm not sure about DBNull, because .NET marshal a null value as VT_EMPTY and not as VT_NULL like DBNull

    Here's what we've found in our testing:
    • DBNull.Value appears as null in both JScript and VBScript.
    • null appears as undefined in JScript and empty in VBScript.
    • new DispatchWrapper(null) appears as undefined in JScript and nothing in VBScript.
    Note that this describes standard .NET marshaling. ClearScript adds another layer to ensure that, for example, host-side null appears as null on the script side. In any case, we agree that (at least) strings, nullable booleans, and nullable numerics should override MarshalNullAsDispatch, and we'll make that fix ASAP.

    Thanks again for your input!

    0 0

    Null in .NET and Null in VbScript are not similar things.
    Suppose you have code that concatenate strings and one of them is null.
    In case of VBScript the result string is null (because ClearScript instead of VT_EMPTY return VT_NULL) and in .NET is not.
    Marshall behaviour of ClearScript is different to default marshaller of .NET and other languages like Delphi. For legacy application that is critical.
    Maybe MarshalNullAsDispatch flag need to replace to the new one like MarshalNullAsNetDefault and marshal values as .NET runtime or expose marshal API that allows override default ClearScript marshaling.
    I don't know maybe I have these troubles because I have big legacy application, anyway It's not very critical for me like memory leaks that you fixed.
    I use modificated version of ClearScript and have my own marshaling, because our objects exposed as COM both to VBScript and Delphi.

    Sorry for my bad english
    using System;
    using Microsoft.ClearScript.Windows;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var person = new Person { FirstName = "Igor"};
                Console.WriteLine("C# full name is '{0}'", person.FirstName + "," + person.LastName);
                using (var scriptEngine = new VBScriptEngine())
                {
                    var script = @"
                        function getFullName
                            getFullName = person.FirstName + "","" + person.LastName
                        end function
                    ";
                    scriptEngine.Execute(script);
                    scriptEngine.Script.person = new Person { FirstName = "Igor"};
                    Console.WriteLine("VBScript full name is '{0}'", scriptEngine.Script.getFullName());
                    Console.ReadKey();
                }
            }
        }
    
        public class Person
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
    
        }
    }

    0 0

    Hi ifle,

    Our view is that these issues are simply the result of bringing together two very different object models.

    It isn't just a matter of null having different meanings. Strings, for example, are full-blown objects in .NET, but in VBScript they're more like primitive values. We could have kept them separate, with no mapping between them, but that would have made ClearScript very painful to use in most scenarios.

    So we tried to choose reasonable mappings for the most common .NET and VBScript types. We know these mappings aren't perfect, and we'll be happy to add flexibility to accommodate legacy scripts as much as possible.

    Maybe MarshalNullAsDispatch flag need to replace to the new one like MarshalNullAsNetDefault and marshal values as .NET runtime

    If we understand correctly, standard .NET marshaling is wrong for your original scenario at the top of this thread, because it always turns .NET null into VBScript empty, whereas your script code expects nothing.

    Our current plan is to go ahead with the change described above. Please let us know if you have any remaining concerns.

    Cheers!

    0 0

    I understand that, It's not simply and I really really appreciate your great work. We convert very big module in legacy application to .NET and will bring together 3 different worlds (.NET, VBScript, Delphi). I don't know which troubles I will meet tomorrow.
    Small example .NET interop does not support interface inheritance, but Delphi do :)
    For now I haven't any remaining concerns.
    I'd like ask if you have any plans expose .NET COM objects as is without wrappers?

    0 0

    If we understand correctly, standard .NET marshaling is wrong for your original scenario at the top of this thread, because it always turns .NET null into VBScript empty, whereas your script code expects nothing.
    No, standard .NET marshaling works as expected, .NET Com object (not string) in case of null marshaled as Nothing, because property Class2 have type of MyClass2 and not string, object and etc.
    That problem of ClearScript marshaling
    public class MyClass
    {
        public MyClass2 Class2 { get; set; } 
    }
    
    public class MyClass2
    {
         
    }

    0 0

    Right, sorry about the confusion. In any case, our planned change should provide the behavior you need when MarshalNullAsDispatch is enabled. Thanks again!

    0 0

    Hi,

    It seems V8 engines are not garbage collected if a script uses a host delegate.

    ```
    public class MyClass
    {
    }

    static void DelegateTest()
    {
    List<WeakReference> enginesWithObject = new List<WeakReference>();
    List<WeakReference> enginesWithDelegate = new List<WeakReference>();

    for (int i = 0; i < 50; i++)
    {
    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("MyClass", typeof(MyClass));
    engine.Execute("var myClass = new MyClass();");
    enginesWithObject.Add(new WeakReference(engine));
    }

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Action", typeof(Action));
    engine.Execute("var action = new Action(function(){});");
    enginesWithDelegate.Add(new WeakReference(engine));
    }
    }

    // Force garbage collection
    GC.Collect();

    int enginesWithObjectCnt = 0, enginesWithDelegateCnt = 0;

    foreach (var item in enginesWithObject)
    {
    if (item.IsAlive)
    {
    enginesWithObjectCnt++;
    }
    }

    foreach (var item in enginesWithDelegate)
    {
    if (item.IsAlive)
    {
    enginesWithDelegateCnt++;
    }
    }
    Console.WriteLine("{0} of {1} engines with objects are alive", enginesWithObjectCnt, enginesWithObject.Count);
    Console.WriteLine("{0} of {1} engines with delegates are alive", enginesWithDelegateCnt, enginesWithDelegate.Count);
    }

    ```

    Note - I'm using latest ClearScript version from 01 June 14.
    After run I get:

    0 of 50 engines with objects are alive
    50 of 50 engines with delegates are alive


    Assuming this issue is fixed, what is more recommended to use for a script callback:
    use a dynamic call to a script function (not type safe) or to create a host delegate (requiring an additional host call) and call it from host.

    Thanks in advance,
    Ron





    0 0

    Hi, I have a c# object I'm adding to the clearscript V8 engine that looks like this:

    public class Helpers
    {
    ...
        public int NTimes(int[] values, int targetValue)
        {
            int answer = 0;
            if (values != null)
            {
                foreach (int val in values)
                {
                    if (val == targetValue)
                        answer++;
                }
            }
    
            return answer;
        }
    
    }

    I add the helpers class (which contains this function) using this: JavascriptContext.AddHostObject("Helpers", Helpers);


    However, when in my javascript I attempt to run code like below I get an argument mismatch exception:

    var items = [$A1, $A2, $A3, $A6, $A9, $A12, $A13, $A16, $A19];

    var value = Helpers.NTimes(items, 3);


    Is this at all related to this thread:
    https://clearscript.codeplex.com/discussions/537917

    Thank you!

    0 0

    Hi,

    I just wanted to point out that I found a solution...

    Here is the modifed NTimes function:
        public int NTimes(dynamic values, int targetValue)
        {
            int answer = 0;
    
            List<int> intVals = new List<int>();
    
    
            for (var i = 0; i < values.length; i++)
                intVals.Add(Convert.ToInt16(values[i]));
    
                foreach (int val in intVals)
                {
                    if (val == targetValue)
                        answer++;
                }
    
    
            return answer;
        }
    
    
    The trick was changing it to a dynamic type and then converting from there into integers.

    0 0

    Hi,

    It seems V8 engines are not garbage collected if a script uses a host delegate.

    ```
    public class MyClass
    {
    }

    static void DelegateTest()
    {
    List<WeakReference> enginesWithObject = new List<WeakReference>();
    List<WeakReference> enginesWithDelegate = new List<WeakReference>();

    for (int i = 0; i < 50; i++)
    {
    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("MyClass", typeof(MyClass));
    engine.Execute("var myClass = new MyClass();");
    enginesWithObject.Add(new WeakReference(engine));
    }

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Action", typeof(Action));
    engine.Execute("var action = new Action(function(){});");
    enginesWithDelegate.Add(new WeakReference(engine));
    }
    }

    // Force garbage collection
    GC.Collect();

    int enginesWithObjectCnt = 0, enginesWithDelegateCnt = 0;

    foreach (var item in enginesWithObject)
    {
    if (item.IsAlive)
    {
    enginesWithObjectCnt++;
    }
    }

    foreach (var item in enginesWithDelegate)
    {
    if (item.IsAlive)
    {
    enginesWithDelegateCnt++;
    }
    }
    Console.WriteLine("{0} of {1} engines with objects are alive", enginesWithObjectCnt, enginesWithObject.Count);
    Console.WriteLine("{0} of {1} engines with delegates are alive", enginesWithDelegateCnt, enginesWithDelegate.Count);
    }

    ```

    Note - I'm using latest ClearScript version from 01 June 14.
    After run I get:

    0 of 50 engines with objects are alive
    50 of 50 engines with delegates are alive


    Assuming this issue is fixed, what is more recommended to use for a script callback:
    use a dynamic call to a script function (not type safe) or to create a host delegate (requiring an additional host call) and call it from host.

    Thanks in advance,
    Ron





    0 0

    Hi,

    It seems V8 engines are not garbage collected if a script uses a host delegate.

    ```
    public class MyClass
    {
    }

    static void DelegateTest()
    {
    List<WeakReference> enginesWithObject = new List<WeakReference>();
    List<WeakReference> enginesWithDelegate = new List<WeakReference>();

    for (int i = 0; i < 50; i++)
    {
    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("MyClass", typeof(MyClass));
    engine.Execute("var myClass = new MyClass();");
    enginesWithObject.Add(new WeakReference(engine));
    }

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Action", typeof(Action));
    engine.Execute("var action = new Action(function(){});");
    enginesWithDelegate.Add(new WeakReference(engine));
    }
    }

    // Force garbage collection
    GC.Collect();

    int enginesWithObjectCnt = 0, enginesWithDelegateCnt = 0;

    foreach (var item in enginesWithObject)
    {
    if (item.IsAlive)
    {
    enginesWithObjectCnt++;
    }
    }

    foreach (var item in enginesWithDelegate)
    {
    if (item.IsAlive)
    {
    enginesWithDelegateCnt++;
    }
    }
    Console.WriteLine("{0} of {1} engines with objects are alive", enginesWithObjectCnt, enginesWithObject.Count);
    Console.WriteLine("{0} of {1} engines with delegates are alive", enginesWithDelegateCnt, enginesWithDelegate.Count);
    }

    ```

    Note - I'm using latest ClearScript version from 01 June 14.
    After run I get:

    0 of 50 engines with objects are alive
    50 of 50 engines with delegates are alive


    Assuming this issue is fixed, what is more recommended to use for a script callback:
    use a dynamic call to a script function (not type safe) or to create a host delegate (requiring an additional host call) and call it from host.

    Thanks in advance,
    Ron




    Comments: Confirmed. Thanks for reporting this issue!

    0 0

    Thanks for posting your solution!

    0 0

    Hi,

    It seems V8 engines are not garbage collected if a script uses a host delegate.

    ```
    public class MyClass
    {
    }

    static void DelegateTest()
    {
    List<WeakReference> enginesWithObject = new List<WeakReference>();
    List<WeakReference> enginesWithDelegate = new List<WeakReference>();

    for (int i = 0; i < 50; i++)
    {
    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("MyClass", typeof(MyClass));
    engine.Execute("var myClass = new MyClass();");
    enginesWithObject.Add(new WeakReference(engine));
    }

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Action", typeof(Action));
    engine.Execute("var action = new Action(function(){});");
    enginesWithDelegate.Add(new WeakReference(engine));
    }
    }

    // Force garbage collection
    GC.Collect();

    int enginesWithObjectCnt = 0, enginesWithDelegateCnt = 0;

    foreach (var item in enginesWithObject)
    {
    if (item.IsAlive)
    {
    enginesWithObjectCnt++;
    }
    }

    foreach (var item in enginesWithDelegate)
    {
    if (item.IsAlive)
    {
    enginesWithDelegateCnt++;
    }
    }
    Console.WriteLine("{0} of {1} engines with objects are alive", enginesWithObjectCnt, enginesWithObject.Count);
    Console.WriteLine("{0} of {1} engines with delegates are alive", enginesWithDelegateCnt, enginesWithDelegate.Count);
    }

    ```

    Note - I'm using latest ClearScript version from 01 June 14.
    After run I get:

    0 of 50 engines with objects are alive
    50 of 50 engines with delegates are alive


    Assuming this issue is fixed, what is more recommended to use for a script callback:
    use a dynamic call to a script function (not type safe) or to create a host delegate (requiring an additional host call) and call it from host.

    Thanks in advance,
    Ron




    Comments: >what is more recommended to use for a script callback: use a dynamic call to a script function (not type safe) or to create a host delegate (requiring an additional host call) and call it from host ​ Script delegates, such as the ones you create in the code above, use dynamic calls under the covers, so our recommendation is that you use them only when calling host methods that require specific delegate types.

    0 0

    Hi,

    It seems V8 engines are not garbage collected if a script uses a host delegate.

    ```
    public class MyClass
    {
    }

    static void DelegateTest()
    {
    List<WeakReference> enginesWithObject = new List<WeakReference>();
    List<WeakReference> enginesWithDelegate = new List<WeakReference>();

    for (int i = 0; i < 50; i++)
    {
    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("MyClass", typeof(MyClass));
    engine.Execute("var myClass = new MyClass();");
    enginesWithObject.Add(new WeakReference(engine));
    }

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Action", typeof(Action));
    engine.Execute("var action = new Action(function(){});");
    enginesWithDelegate.Add(new WeakReference(engine));
    }
    }

    // Force garbage collection
    GC.Collect();

    int enginesWithObjectCnt = 0, enginesWithDelegateCnt = 0;

    foreach (var item in enginesWithObject)
    {
    if (item.IsAlive)
    {
    enginesWithObjectCnt++;
    }
    }

    foreach (var item in enginesWithDelegate)
    {
    if (item.IsAlive)
    {
    enginesWithDelegateCnt++;
    }
    }
    Console.WriteLine("{0} of {1} engines with objects are alive", enginesWithObjectCnt, enginesWithObject.Count);
    Console.WriteLine("{0} of {1} engines with delegates are alive", enginesWithDelegateCnt, enginesWithDelegate.Count);
    }

    ```

    Note - I'm using latest ClearScript version from 01 June 14.
    After run I get:

    0 of 50 engines with objects are alive
    50 of 50 engines with delegates are alive


    Assuming this issue is fixed, what is more recommended to use for a script callback:
    use a dynamic call to a script function (not type safe) or to create a host delegate (requiring an additional host call) and call it from host.

    Thanks in advance,
    Ron





    0 0

    Hi,

    It seems V8 engines are not garbage collected if a script uses a host delegate.

    ```
    public class MyClass
    {
    }

    static void DelegateTest()
    {
    List<WeakReference> enginesWithObject = new List<WeakReference>();
    List<WeakReference> enginesWithDelegate = new List<WeakReference>();

    for (int i = 0; i < 50; i++)
    {
    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("MyClass", typeof(MyClass));
    engine.Execute("var myClass = new MyClass();");
    enginesWithObject.Add(new WeakReference(engine));
    }

    using (var engine = new V8ScriptEngine())
    {
    engine.AddHostType("Action", typeof(Action));
    engine.Execute("var action = new Action(function(){});");
    enginesWithDelegate.Add(new WeakReference(engine));
    }
    }

    // Force garbage collection
    GC.Collect();

    int enginesWithObjectCnt = 0, enginesWithDelegateCnt = 0;

    foreach (var item in enginesWithObject)
    {
    if (item.IsAlive)
    {
    enginesWithObjectCnt++;
    }
    }

    foreach (var item in enginesWithDelegate)
    {
    if (item.IsAlive)
    {
    enginesWithDelegateCnt++;
    }
    }
    Console.WriteLine("{0} of {1} engines with objects are alive", enginesWithObjectCnt, enginesWithObject.Count);
    Console.WriteLine("{0} of {1} engines with delegates are alive", enginesWithDelegateCnt, enginesWithDelegate.Count);
    }

    ```

    Note - I'm using latest ClearScript version from 01 June 14.
    After run I get:

    0 of 50 engines with objects are alive
    50 of 50 engines with delegates are alive


    Assuming this issue is fixed, what is more recommended to use for a script callback:
    use a dynamic call to a script function (not type safe) or to create a host delegate (requiring an additional host call) and call it from host.

    Thanks in advance,
    Ron




    Comments: Fix posted [here](https://clearscript.codeplex.com/SourceControl/changeset/3d371d6388d2320e851b270a9984a2432e331f6f).

    0 0

    The update is now available. Cheers!

    0 0

    We've posted an update that includes the new property ScriptEngine.DisableTypeRestriction for controlling this behavior at the engine level.

older | 1 | .... | 36 | 37 | (Page 38) | 39 | 40 | .... | 115 | newer