Two WebAssembly Related Questions

I’ve been playing with a Water/C#/Island/DelphiVCL/WebAssembly project

Things or going pretty well so far.

I can call my project’s c# methods from JavaScript, no problem. What I can’t figure out is how to call a JavaScript function from the c# (but ultimately WebAssembly) code.

What I want to do is call a JavaScript function, passing it a string variable, because that function already exists and makes a RO service call to my RO Server.

The second question has to do with running/debugging from within Water. I found this article: https://blogs.remobjects.com/2018/01/12/webassembly-swift-c-java-and-oxygene-in-the-browser/ which says that Water can start a web server process, start chrome in debug mode, and run my project. That would be handy because up to this point I have been using an external web server with chrome and debugging isn’t integrated with Water that way.

I think I probably just need a setting chage, but I can’t figure out what.

I have the path to Chrome setup under Tools -> Options -> Paths, and when I run my project I do see Chrome run for a split second and then close again.

In my project settings I have this (which were the default):

Debugging
    Enable Assertions: YES for User and Debug, NO for Release Project and Default
    Generate Debug Symbols: YES for User and  Debug, NO for Release Project and Default
Running
    Debug index.html file: Web\index.html 
    Debug Root Folder: (blank)
    Debug URL: (blank)
    Test Project: (blank)

Any help would be greatly appreciated :slight_smile:

Hmm. any crash info in the Event log? any debug output in the Build or Debug log views in Water? anything in %APPDATA%\...\Water.log?

Nothing in the Windows event logs.
Nothing in the console.
Last line of the build logs says “Solution ‘VclRoTest’ built successfully.”
Here is the Water.log:

2018-10-31 19:00:08 Ctrl+: R (, -1)
2018-10-31 19:00:08 parameters {
  "Arguments": [
  ],
  "EnvironmentVariables": {
  },
  "Mode": "Island",
  "SubMode": "WebAssembly",
  "CaptureOutput": true,
  "CrossBox": "Local",
  "LocalExecutable": "C:\\devdata\\water\\testing\\vcl-ro-wasm-test\\Bin\\Debug\\WebAssembly\\wasm32\\RemObjectsElements.js",
  "Architecture": "wasm",
  "RemoteExecutable": "C:\\devdata\\water\\testing\\vcl-ro-wasm-test\\Bin\\Debug\\WebAssembly\\wasm32\\RemObjectsElements.js",
  "WebAssemblyDebugUrl": "index.html",
  "WebAssemblyHttpPort": 0,
  "WebAssemblyHttpRootPath": "C:\\devdata\\water\\testing\\vcl-ro-wasm-test\\Web",
  "WebAssemblyHttpSubFolderName": "wasm",
  "WebAssemblyHttpSubFolderPath": "C:\\devdata\\water\\testing\\vcl-ro-wasm-test\\Bin\\Debug\\WebAssembly\\wasm32",
  "StrictBreakpoints": true
}

Could the problem be that the port is 0?

Edit: Correction - this is what is in the console:

~> Process VclRoTest started
The WebSocket protocol is not supported on this platform.
~> Process VclRoTest terminated with exit code 0

Another Edit: Running on Windows 7 64-bit

Curious. @ck?

ah damn; WebSocket isn’t supported on .net for win7 (websocket is only used for debugging, but is still a requirement for debugging). Any chance you can use win8 or higher (in a virtual machine or otherwise)?

@ck, can w make this emit a more clear error?

done.

1 Like

Thanks guys.

Upgrading to Win 10. I’ve avoided it as long as possible I guess. If I had the choice I’d still be running XP :stuck_out_tongue:

Any thoughts on my question about how to call a JavaScript function from within WebAssembly/C# ?

Thanks

What do you have? a global function? a variable with a function in it?

You can use WebAssembly.Global to access the global object, so for example:

WebAssembly.Global['functionname'](arguments)

I believe what I’m trying to do is call a global javascript function. Here is my very simple test case:

index.html

<html>
    <head>
        <title>WasmJsLink Test Page</title>
        <script lang="javascript" src="wasm/RemObjectsElements.js"></script>
        <script lang="javascript" src="wasm/WasmJsLink.js"></script>
    </head>
    <body>
    <h1>WasmJsLink Test Page</h1>
    <script lang="javascript">
        WasmJsLink.instantiate("wasm/WasmJsLink.wasm").then(function (result) {
            console.log("WebAssembly file WasmJsLink.wasm has been loaded.");
            var program = result.Program();
            program.ShowGui();
        });

        function logsomething(something) {
            console.log('Logging something...');
        }
    </script>
    </body>
</html>

Program.cs

using RemObjects.Elements.RTL.Delphi;
using RemObjects.Elements.RTL.Delphi.VCL;

namespace WasmJsLink
{
    [Export]
    public class Program
    {
        public static TForm Form1;

        public void ShowGui()
        {
            Application = new TApplication(null);
            Application.Initialize();
            Application.CreateForm(typeOf(TForm), ref Form1);
            Application.Run();

            TButton Button1 = new TButton(Form1);
            Button1.Name = "Button1";
            Button1.Caption = "Button1";
            Button1.Left = 64;
            Button1.Top = 64;
            Button1.Width = 75;
            Button1.Height = 25;
            Button1.OnClick = Button1Click;
            Button1.Parent = Form1;
        }

        public void Button1Click(TObject sender)
        {
            TButton button = sender as TButton;
            string toLog = "log this";
            WebAssembly.Global["dosomething"](toLog);
            button.Caption = "Clicked";
        }
    }
}

note logsomething vs dosomething?

Thanks. I’ve tried so many things, I must have left that mismatched.

However even after fixing that, I still can’t get it to go.

This is what chrome debugger is giving me:

GET http://localhost:8888/favicon.ico 404 (Not Found)
(index):11 WebAssembly file WasmJsLink.wasm has been loaded.
RemObjectsElements.js:277 Fatal exception in WebAssembly!
RemObjectsElements.js:277 Exception: RemObjects.Elements.System.FormatException: bad format.
wasm-01b2223e-50:27 Uncaught RuntimeError: unreachable
    at ElementsRaiseException (wasm-function[50]:74)
    at .Lms_t28_RemObjects_d_Elements_d_System_d_Convert14_RaiseFormatException (wasm-function[5696]:94)
    at .Lms_i325_Parsens (wasm-function[2531]:123)
    at .Lms_t28_RemObjects_d_Elements_d_System_d_Convert7_ToInt32no (wasm-function[5713]:2706)
    at .Lmi_t31_RemObjects_d_Elements_d_System_d_EcmaScriptObject9_GetMembernsni32na_o (wasm-function[6889]:167)
    at .L_intf__rtti_t31_RemObjects_d_Elements_d_System_d_EcmaScriptObject_vmthelper0 (wasm-function[6910]:414)
    at .Lms_t2f_RemObjects_d_Elements_d_System_d_DynamicHelpers9_GetMembernonsni32na_o (wasm-function[1056]:596)
    at mi_t14_WasmJsLink_d_Programc_Button1Clickno (wasm-function[7456]:591)
    at .Lmi_t33_RemObjects_d_Elements_d_RTL_d_Delphi_d_TNotifyEvent6_Invokeno (wasm-function[166]:63)
    at .Lmi_tnt35_RemObjects_d_Elements_d_RTL_d_Delphi_d_VCL_d_TControl18__l__g_c____DisplayClass01e__l_PlatformSetOnClick_g_b____0nt31_RemObjects_d_Elements_d_System_d_EcmaScriptObject (wasm-function[1076]:43)

Chris, while we are checking the way Carlo said, please use this code to call your js function:
var lWindow = WebAssembly.GetWindowObject();
var lString = “something”;
lWindow.logsomething(lString);

Works great!!!

Thanks

1 Like