How does .JSLIB file work?

I can’t understand how to work with .jslib files. I don’t understand the syntax of this type of file. Also I couldn’t find any easy explanation of it

The problem started when I tried to make two functions global for all .jslib files:

/**
 * @param {string} str
 * @returns {string}
 */
function StrJSToStrCS (str) {
   const bufferSize = lengthBytesUTF8(str) + 1;
   const buffer = _malloc(bufferSize);
   stringToUTF8(str, buffer, bufferSize);
   return buffer;
}

/**
 * @param {string} str
 * @returns {string}
 */
function StrCSToStrJS (str) {
   return UTF8ToString(str);
}

What I already tried:

  • To define these two functions in the same file
function StrJSToStrCS (str) {
  const bufferSize = lengthBytesUTF8(str) + 1;
  const buffer = _malloc(bufferSize);
  stringToUTF8(str, buffer, bufferSize);
  return buffer;
}
   
function StrCSToStrJS (str) {
  return UTF8ToString(str);
}
   
const lib = {
  Hello: function () {
    return StrJSToStrCS('HELLO WORLD!');
  },

  ConsoleLog: function (str) {
    console.log(StrCSToStrJS(str));
  }
};
   
mergeInto(LibraryManager.library, lib);
  • To define these two functions in script tag in .html after reading this. If it’s important the script tag I inserted at the bottom of body tag
<script>
function StrJSToStrCS (str) {
  const bufferSize = lengthBytesUTF8(str) + 1;
  const buffer = _malloc(bufferSize);
  stringToUTF8(str, buffer, bufferSize);
  return buffer;
}
   
function StrCSToStrJS (str) {
  return UTF8ToString(str);
}
</script>
const lib = {
  Hello: function () {
    return StrJSToStrCS('HELLO WORLD!');
  },

  ConsoleLog: function (str) {
    console.log(StrCSToStrJS(str));
  }
};
   
mergeInto(LibraryManager.library, lib);
  • To define these functions in .jspre file after reading this:
    “the .jspre files are added to the build using the --pre-js option, while the .jslib are added using the --js-library option”
    .jspre file:
function StrJSToStrCS (str) {
  const bufferSize = lengthBytesUTF8(str) + 1;
  const buffer = _malloc(bufferSize);
  stringToUTF8(str, buffer, bufferSize);
  return buffer;
}
   
function StrCSToStrJS (str) {
  return UTF8ToString(str);
}

.jslib file:

const lib = {
  Hello: function () {
    return StrJSToStrCS('HELLO WORLD!');
  },

  ConsoleLog: function (str) {
    console.log(StrCSToStrJS(str));
  }
};
   
mergeInto(LibraryManager.library, lib);
  • To simply define these functions as methods in the same object:
const lib = {
  StrJSToStrCS: function(str) {
    const bufferSize = lengthBytesUTF8(str) + 1;
    const buffer = _malloc(bufferSize);
    stringToUTF8(str, buffer, bufferSize);
    return buffer;
  },
   
  StrCSToStrJS: function(str) {
    return UTF8ToString(str);
  },
       
  Hello: function() {
    return this.StrJSToStrCS('HELLO WORLD!');
  },
       
  ConsoleLog: function(str) {
    console.log(this.StrCSToStrJS(str));
  }
}
   
mergeInto(LibraryManager.library, lib);

But whatever I do, he writes every time in console that StrJSToStrCS/StrCSToStrJS is not defined

I don’t understand at all why the last method doesn’t work. Isn’t lib just a simple object?

Is it possible to make these two functions global for all .jslib files?

Functions defined in a .jslib file will have “" prefixed to the function name when compiled. Therefore, call the function name with "” at the beginning.

_StrJSToStrCS('HELLO WORLD!');

However, in the case of SendMessage(), string can be passed as it is without converting it to a pointer, but is there any reason why it is passed as a pointer?

Finally I found the answer!

In .jspre file I had to write:

Module.StrJSToStrCS = function(str) {
   const bufferSize = lengthBytesUTF8(str) + 1;
   const buffer = _malloc(bufferSize);
   stringToUTF8(str, buffer, bufferSize);
   return buffer;
}

Module.StrCSToStrJS = function(str) {
   return UTF8ToString(str);
}

and then in .jslib file call these functions like this:

const lib = {
    Hello: function() {
        return gameInstance.Module.StrJSToStrCS('HELLO WORLD!');
    },

    ConsoleLog: function(str) {
        console.log(gameInstance.Module.StrCSToStrJS(str));
    }
}

mergeInto(LibraryManager.library, lib);

No, I just didn’t see the argument type error so I didn’t know it :slight_smile:
I edited my question

I will try your method. Will these function defined in .jslib file visible in other .jslib files?

Even if there are multiple .jslibs, they are all expanded in one scope, so you can call functions defined in other .jslibs.

For example, you can create JSLIBTest_Foo.jslib and JSLIBTest_Bar.jslib as follows and call functions defined in JSLIBTest_Bar from functions defined in JSLIB_Foo.

// JSLIBTEST_Foo.jslib
const foo = {
    JSLIBTest_Foo: function() {
        _JSLIBTest_Bar();
    }
};
mergeInto(LibraryManager.library, foo);
// JSLIBTest_Bar.jslib
const bar = {
    JSLIBTest_Bar: function() {
        console.log('---bar---');
    }
};
mergeInto(LibraryManager.library, bar);
// Test C# Code
using System.Runtime.InteropServices;
using UnityEngine;

public class JSLIBTest : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void JSLIBTest_Foo();

    [DllImport("__Internal")]
    private static extern void JSLIBTest_Bar();

    private void Start()
    {
        JSLIBTest_Foo();
    }
}

8690919--1172559--ss_t.png

1 Like

So, if you create multiple .jslibs, if you have the same function name in another .jslib, it may be overwritten, so be careful with the function name.

Thank you so much! After your words I went to documentation again and saw that at the of note which directly above this sections says exactly what you said. Forgive me for my blindness :slight_smile: