microsoft / ClearScript

A library for adding scripting to .NET applications. Supports V8 (Windows, Linux, macOS) and JScript/VBScript (Windows).
https://microsoft.github.io/ClearScript/
MIT License
1.77k stars 148 forks source link

Issue with calling JavaScript functions defined as function from ClearScript in C# #582

Closed emisaez closed 4 months ago

emisaez commented 4 months ago

Hello,

I'm using ClearScript in my C# application to execute JavaScript scripts, and I've encountered an issue when trying to call functions defined in JavaScript from C#. Specifically, I'm using an onJoin function in my JavaScript script to handle events when a user joins, but I can only call this function from C# if it's defined with the syntax onJoin = function(user) { }. I haven't been able to make it work when defined as function onJoin(user) { }.

Here's an example of how I'm trying to call the function from C# and how the JavaScript script looks: // C# code using ClearScript to execute JavaScript

this.Engine = new V8ScriptEngine(scriptName, flags); this.Engine.Evaluate(@"function onJoin(user) { /* implementation */ }");

// Calling the function from C# this.Engine.Invoke("onJoin", user); // This does not work this.Engine.Script.onJoin(user); // This does not work

Is there any specific configuration I need to apply in ClearScript to correctly call functions defined as function from C#? I appreciate any guidance or suggestions you can offer.

Thank you!

ClearScriptLib commented 4 months ago

Hi @emisaez,

We can't reproduce this issue. Here's our test program:

using Microsoft.ClearScript.V8;
using var engine = new V8ScriptEngine();
engine.AddHostType(typeof(Console));
engine.Evaluate("function onJoin(user) { Console.WriteLine(user); }");
engine.Script.onJoin("Hello!");
engine.Invoke("onJoin", "World!");

This program produces the expected output:

Hello!
World!

Is there something you're doing differently? Also, what incorrect behavior are you seeing?

Thanks!

emisaez commented 4 months ago

Yes, I'm sorry, I had something different that I didn't realize. I already solved my problem, but I was left with some doubts because, as I mentioned before, the code only worked when calling the function with a specific syntax 'onJoin = function(user){}'

this.Engine = new V8ScriptEngine(scriptName, flags); this.Engine.Evaluate(@"function onJoin(user) { /* implementation */ }");

This was the different code: var code = System.IO.File.ReadAllText(path); var uri = new Uri(System.IO.Path.Combine(this.Path, this.ScriptName), UriKind.RelativeOrAbsolute); var docInfo = new DocumentInfo() { Category = ModuleCategory.Standard, Flags = DocumentFlags.None, SourceMapUri = uri };

this.Engine.Execute(docInfo, code); // it does not work

It was solved by removing docInfo:

this.Engine.Execute(code); // it works

// event this.Engine.Invoke("onJoin", user); // it works this.Engine.Script.onJoin(user); // it works

ClearScriptLib commented 4 months ago

It was solved by removing docInfo:

Ah, right. Inside a module, function statements do not create global properties.

Please reopen this issue if you have additional questions or comments on this topic. Thank you!