从 Unity 弃用两个跟网页相关的API之后, 就开始使用 jslib 了:
[Obsolete("Application.ExternalEval is deprecated. See https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html for alternatives.")] public static void ExternalEval(string script); [Obsolete("Application.ExternalCall is deprecated. See https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html for alternatives.")] public static void ExternalCall(string functionName, params object[] args);
因为我之前也没用过 WebGL 相关的东西, 有点不明所以, 也是上一篇中提到的
WebGL 内嵌网页的一种解决方案
从 Unity 调用 javascript 代码为什么用的是 [DllImport("__Internal")] 的形式, 到 javascript 代码获取 C# 传来的数组为什么会这么复杂, 到甚至字符串的传递都不是正常逻辑来说, 既然注入 JavaScript 这么绕, 那肯定是为了性能了, 看了一下编译方案, 频繁出现 Emscripten 这个字眼, 查了一下, 就是这个编译器, 在编辑器文件夹下也找到了 :
Emscripten 看介绍 :
Emscripten is a toolchain for compiling to asm.js and WebAssembly, built using LLVM, that lets you run C and C++ on the web at near-native speed without plugins.
是把 C / C++ 编译成特殊的 JavaScript 代码 asm.js 获得很快的运行速度, 所以工程内的代码都会通过 IL2CPP 生成 C++ 代码, 然后转换成 asm.js 和 WebAssembly, 看看生成出来的项目目录下:
我觉得这些 xxx.asm.ooo.unityweb 的东西应该就是 WebAssembly 的二进制代码吧, 那个 xxx.data.unityweb 应该是资源包, 而 UnityLoader.js 应该就是 asm.js 的代码吧 :
反正这些都是自动生成的, 跟我无关, 知道原理就行了, 不过对于 .jslib 文件, 就不清楚它是怎样编译的或者是个什么对象了......
首先它的代码近似于 javascript, 并且是在网页端的代码, 可是它的数据传输方式又类似于二进制数据, 其实它就是 asm.js ? 我从其它地方找到一个 C++ 调用 JS 代码的例子来看 :
#include#include <string> void Alert(const std::string & msg) { EM_ASM_ARGS({ var msg = Pointer_stringify($0); // 跟 .jslib 里的代码几乎一样的 alert(msg); }, msg.c_str()); } int main() { Alert("Hello from C++!"); }
上面代码通过 Emscripten 编译成为 asm.js 文件, 它接受的是C++的字符串输入, 而我们写的 .jslib 文件是这样的 :
HelloString: function (str) { window.alert(Pointer_stringify(str)); },
并且C#调用引用的方法通过 [DllImport("__Internal")] 来的, 猜测生成代码的过程就是把这个方法生成了C++对应的方法, 才能这样调用 :
--------- .jslib --------------------- var myLib = { HelloString: function (str) { window.alert(Pointer_stringify(str)); }, }; mergeInto(LibraryManager.library, myLib); ------- 把它生成C++代码 ---------------- #include#include <string> #include _DLLExport void HelloString(const char* c) { std::string str = c; // 不知道对不对, 差不多这个意思 EM_ASM_ARGS({ window.alert(Pointer_stringify($0)); // 把window.alert(Pointer_stringify(str)); 改成对应的index $0 }, str.c_str()); } ------- C# 引用C++代码 ---------------- [DllImport("__Internal")] private static extern void HelloString(string str);
或者 Emscripten 有它的标准, 直接
一些参考 :
http://www.ruanyifeng.com/blog/2017/09/asmjs_emscripten.html
https://www.ucloud.cn/yun/92400.html
一些官方信息 :
https://www.sitepoint.com/asm-js-and-webgl-for-unity-and-unreal-engine/
https://blogs.unity3d.com/2018/08/15/webassembly-is-here/