Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. The 2023.1 beta is now available for testing. To find out what's new, have a look at our 2023.1 feature highlights.
    Dismiss Notice

How to call C# methods from JavaScript?

Discussion in 'Project Tiny' started by SINePrime, Mar 14, 2020.

  1. SINePrime

    SINePrime

    Joined:
    Jan 24, 2019
    Posts:
    54
    Sorry if this is considered a duplicate of this thread, I didn't want to hijack/ necro that thread.

    I'm trying to invoke C# methods from JavaScript, and having trouble accomplishing this.

    Are we meant to use `ccall` and `cwrap`, as outlined here? When I tried to add `EXTRA_EXPORTED_RUNTIME_METHODS['cwrap']` to the arguments of my Emscripten build settings, the build tools threw an error:
    >error: Emscripten LinkerSettings contains setting for which a dedicated parameter exists: EXTRA_EXPORTED_RUNTIME_METHODS (System.InvalidOperationException)

    Is there somewhere I am meant to configure this outside the Emscripten settings?

    Another method I see is using `dynCall` methods, but documentation on these methods is scarce, and I've had no luck with all previous examples.

    I'm at a bit of a loss on how to proceed. Any ideas or documentation?
     
  2. SINePrime

    SINePrime

    Joined:
    Jan 24, 2019
    Posts:
    54
    With a bit of digging, I figured out there were multiple dynCall variants; the only variants that worked for me was the dynCall_* variant:
    Code (CSharp):
    1. dynCall_v(callback); // this works
    2. //dynCall('v', callback); // ReferenceError: dynCall is not defined
    3. //Module['dynCall_v'](callback); // TypeError: Module.dynCall_v is not a function
    I'll be sharing an example Project Tiny repo with bidirectional C# <-> JavaScript shortly.
     
    facundo_unity961 likes this.
  3. SINePrime

    SINePrime

    Joined:
    Jan 24, 2019
    Posts:
    54
    ̶I̶ ̶m̶a̶d̶e̶ ̶a̶n̶ ̶e̶x̶a̶m̶p̶l̶e̶ ̶p̶r̶o̶j̶e̶c̶t̶ ̶w̶i̶t̶h̶ ̶i̶n̶t̶e̶r̶o̶p̶e̶r̶a̶b̶i̶l̶i̶t̶y̶ ̶b̶e̶t̶w̶e̶e̶n̶ ̶C̶#̶ ̶a̶n̶d̶ ̶J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ ̶h̶e̶r̶e̶.̶ ̶T̶h̶e̶ ̶J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ ̶t̶o̶ ̶C̶#̶ ̶e̶x̶a̶m̶p̶l̶e̶s̶ ̶r̶e̶q̶u̶i̶r̶e̶ ̶y̶o̶u̶ ̶t̶o̶ ̶p̶a̶s̶s̶ ̶t̶h̶e̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶y̶o̶u̶ ̶w̶a̶n̶t̶ ̶t̶o̶ ̶c̶a̶l̶l̶ ̶a̶s̶ ̶a̶ ̶d̶e̶l̶e̶g̶a̶t̶e̶.̶

    If anyone has info on how to call an arbitrary static C# function from JavaScript in Unity, please let me know!

    EDIT: Removed project link.
     
    Last edited: Mar 4, 2021
  4. Savign

    Savign

    Joined:
    Nov 15, 2013
    Posts:
    3
    Hey Sine, thanks for putting up the example - I'm at a bit of a loss to how to call the callback methods from the javascript console though.

    If you could offer any advice that'd be greatly appreciated!
     
    Rangerz132 likes this.
  5. Rangerz132

    Rangerz132

    Joined:
    Feb 3, 2019
    Posts:
    34
    Hi @SINePrime. I'm currently building a game with Unity Tiny and I need to call C# function from JS. I'm able to call JS function from C# and to do callbacks like this => C# to JS to C#, but I'm not able to call C# function from JS. I'm not able to get the example project you mentionned earlier in your post.
     
  6. SINePrime

    SINePrime

    Joined:
    Jan 24, 2019
    Posts:
    54
    Sorry, I removed the project link because the official Getting Started guide now contains JavaScript interoperability instructions.

    As far as calling arbitrary C# from JavaScript, I don't think it's possible. You'll have to do something like pass all the C# delegates you need to JavaScript using an initialization function.
     
  7. Rangerz132

    Rangerz132

    Joined:
    Feb 3, 2019
    Posts:
    34
    I talked to one of the Tiny Dev member and said that I have to basically use the callaback approach. C# needs to give JS a callback method to use, and then JS can call it. However, I don't know how JS can call the callback..
     
  8. gtk2k

    gtk2k

    Joined:
    Aug 13, 2014
    Posts:
    243
    C# function from JS sample.

    Code (CSharp):
    1. using System;
    2. using Unity.Entities;
    3. using System.Runtime.InteropServices;
    4. using AOT;
    5.  
    6. public class MySystem : SystemBase
    7. {
    8.     delegate void FizzBuzzDelegate(int num, string fizzBuzz);
    9.  
    10.     [DllImport("__Internal")]
    11.     private static extern void callbackInit(FizzBuzzDelegate callback);
    12.  
    13.     [MonoPInvokeCallback(typeof(FizzBuzzDelegate))]
    14.     private static void FizzBuzzCallback(int num, string fizzBuzz)
    15.     {
    16.         Console.WriteLine("[C#] " + num + ":" + fizzBuzz);
    17.     }
    18.  
    19.     protected override void OnCreate()
    20.     {
    21.         callbackInit(FizzBuzzCallback);
    22.     }
    23.  
    24.     protected override void OnUpdate()
    25.     {
    26.     }
    27. }
    28.  
    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {
    2.     $num: 0,
    3.     $fizzBuzzCallbackPointer: 0,
    4.  
    5.     $timerFunc: function () {
    6.         setInterval(function () {
    7.             num++;
    8.             var fizzBuzz = '';
    9.             if (!(num % 15)) fizzBuzz = 'FizzBuzz';
    10.             else if (!(num % 3)) fizzBuzz = 'Fizz';
    11.             else if (!(num % 5)) fizzBuzz = 'Buzz';
    12.             else if (!fizzBuzz) fizzBuzz = num.toString();
    13.             var len = lengthBytesUTF8(fizzBuzz) + 1;
    14.             var ptr = _malloc(len);
    15.             stringToUTF8(fizzBuzz, ptr, len);
    16.             dynCall_vii(fizzBuzzCallbackPointer, num, ptr);
    17.             _free(ptr);
    18.         }, 1000);
    19.     },
    20.  
    21.     callbackInit__deps: ['$fizzBuzzCallbackPointer', '$num', '$timerFunc'],
    22.     callbackInit: function (callbackPtr) {
    23.         fizzBuzzCallbackPointer = callbackPtr;
    24.         timerFunc();
    25.     }
    26. });
     
    Last edited: Mar 5, 2021
    Rangerz132 and Maras like this.
  9. Rangerz132

    Rangerz132

    Joined:
    Feb 3, 2019
    Posts:
    34
    Thanks a lot! I was able to do exactly what I wanted to do! It is really appreciated! Also do you know if there is a way to know if our game is LOADED in the browser and how we can UNLOAD it?
     
  10. unity_-xVksTSNs-py8g

    unity_-xVksTSNs-py8g

    Joined:
    Jul 13, 2018
    Posts:
    1
    Quick question, i'm attempting to work on a solution to this as I think there isnt a way.... but is there away to have external JS (so perhaps in the HTML page itself rather than as part of the 'mergeInto' embedded JS) call CSharp functions?