[英]Returning a byte array from JavaScript to Emscripten/Unity Web Assembly
我有一些 JavaScript 数据,我正在对其进行序列化,以便 Unity 可以将其作为 byte[] 数组使用,如此处一般所述。 我想通过这样的 jslib 接口将这些数据公开给 Unity:
[DllImport("__Internal")]
private static extern byte[] GetByteArray();
我尝试使用 emscripten 中的内置方法从 JavaScript 桥接我的值:
GetByteArray: function () {
var myTypedArray = new Uint8Array([10, 20, 30, 40, 50]);
var buf = _malloc(myTypedArray.length * myTypedArray.BYTES_PER_ELEMENT);
writeArrayToMemory(myTypedArray, buf);
return buf;
},
不幸的是,这不起作用——webassembly C# 只将 0 长度数组视为返回类型。 我还尝试HEAPU8.set(myTypedArray, buf)
类的东西。
问题:
我希望你找到了解决你的问题的方法。 这是我的(非常hacky的解决方案),但它有效:
jslib
GetByteArray: function(){
var array = new Uint8Array([10, 20, 30, 40, 50]);
var str = array.toString();
str = '[' + str + ']';
unityInstance.sendMessage('gameObject', 'ByteArrayAvailable', str);
}
C#
#if UNITY_WEBGL && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void GetByteArray();
#endif
...
void CallWebGL()
{
GetByteArray();
}
void ByteArrayAvailable(string byteArrayStr)
{
var byteArray = JsonConvert.DeserializeObject<byte[]>(byteArrayStr);
}
您需要将 Newtonsoft.Json.dll 添加到您的插件文件夹中以使其工作,但这是我发现使其工作的唯一简单方法:)
秘诀是有一个方法来实例化字节数组并从 js 上下文中调用它。 实例化数组的方法然后调用实际填充字节数组的js方法。 这是一个两步过程。
C# 边
[DllImport("__Internal", EntryPoint = "getByteArrayTmp")]
private static extern void getByteArrayTmp(Action<int> instantiateByteArrayCallback);
[DllImport("__Internal", EntryPoint = "getByteArray")]
private static extern void getByteArray(Action callback, byte[] byteArray);
private static event Action callbackEvent;
public static byte[] byteArray;
[MonoPInvokeCallback(typeof(Action))]
private static void callback() {
callbackEvent?.Invoke();
callbackEvent = null;
}
[MonoPInvokeCallback(typeof(Action<int>))]
private static void instantiateByteArrayCallback(int size) {
byteArray = new byte[size];
getByteArray(callback, byteArray);
}
用户实际调用的方法是
public static void getByteArray(Action callback) {
#if UNITY_WEBGL && !UNITY_EDITOR
callbackEvent = null;
callbackEvent += callback;
getByteArrayTmp(instantiateByteArrayCallback);
#endif
}
在 js 方面
getByteArrayTmp: function(instantiateByteArrayCallback) {
const byteArray = new Uint8Array([21, 31]);//example
Module["yourplugin"].byteArray = byteArray;
Module.dynCall_vi(instantiateByteArrayCallback, byteArray.length);
},
getByteArray: function(callback, byteArray) {
Module.HEAPU8.set(Module["yourplugin"].byteArray, byteArray);
Module.dynCall_v(callback);
},
这比使用字符串作为中间体要快几倍。 您可以像这样在不到一秒的时间内将超过 20MB 的数据从 js 传输到 Unity,而使用字符串方法则需要几秒钟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.